Skip to content

Commit 41b3fb0

Browse files
committed
Extend PAM+NSS sharelink access to cover all three access modes in order to
support access from sshd+sftpsubsys service, too. Simply adjusts the existing read-write sharelink test and auth to instead loop through the three access modes in turn and do the similar test for each. Minor adjustments to continue until one succeeds or all have been tried. The existing test+auth code is purposefully kept unindented in this version to make the diff simple to review. Will follow-up with a separate commit which only indents to fit loop nesting to keep that change simple as well.
1 parent 5d294e1 commit 41b3fb0

File tree

3 files changed

+42
-11
lines changed

3 files changed

+42
-11
lines changed

mig/src/include/auth/migauth.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,14 @@
107107
#ifndef SHARELINK_LENGTH
108108
#define SHARELINK_LENGTH 42
109109
#endif
110-
#ifndef SHARELINK_SUBDIR
111-
#define SHARELINK_SUBDIR "read-write"
110+
#ifndef SHARELINK_RW_DIR
111+
#define SHARELINK_RW_DIR "read-write"
112+
#endif
113+
#ifndef SHARELINK_RO_DIR
114+
#define SHARELINK_RO_DIR "read-only"
115+
#endif
116+
#ifndef SHARELINK_WO_DIR
117+
#define SHARELINK_WO_DIR "write-only"
112118
#endif
113119
#endif /* !DISABLE_SHARELINK */
114120

mig/src/libnss-mig/libnss_mig.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,18 +177,23 @@ _nss_mig_getpwnam_r(const char *name,
177177
#ifdef ENABLE_SHARELINK
178178
/* Optional anonymous share link access:
179179
- username must have fixed length matching get_sharelink_length()
180-
- get_sharelink_home()/SHARELINK_SUBDIR/username must exist as a symlink
180+
- get_sharelink_home()/SHARELINK_X_DIR/username must exist as a symlink
181181
- username and password must be identical or pub key fit authorized_keys
182182
*/
183183
if (keep_trying && name_len == get_sharelink_length()) {
184184
WRITELOGMESSAGE(LOG_DEBUG, "Checking for sharelink: %s\n", name);
185+
186+
char sharelink_modes[][10] = { SHARELINK_RW_DIR, SHARELINK_RO_DIR, SHARELINK_WO_DIR };
187+
for (size_t i = 0; i < sizeof(sharelink_modes) / sizeof(sharelink_modes[0]); i++)
188+
{
189+
185190
memset(pathbuf, 0, PATH_BUF_LEN);
186191
if (PATH_BUF_LEN ==
187192
snprintf(pathbuf, PATH_BUF_LEN, "%s/%s/%s",
188-
get_sharelink_home(), SHARELINK_SUBDIR, name)) {
193+
get_sharelink_home(), sharelink_modes[i], name)) {
189194
WRITELOGMESSAGE(LOG_WARNING,
190195
"Path construction overflow for: %s/%s/%s\n",
191-
get_sharelink_home(), SHARELINK_SUBDIR, name);
196+
get_sharelink_home(), sharelink_modes[i], name);
192197
return NSS_STATUS_NOTFOUND;
193198
}
194199
/* Make sure prefix of direct sharelink target is user home */
@@ -222,8 +227,12 @@ _nss_mig_getpwnam_r(const char *name,
222227
is_share = 1;
223228
pathlen =
224229
strlen(get_sharelink_home()) +
225-
strlen(SHARELINK_SUBDIR) + name_len + 2;
230+
strlen(sharelink_modes[i]) + name_len + 2;
231+
break;
226232
}
233+
234+
}
235+
227236
}
228237
WRITELOGMESSAGE(LOG_DEBUG, "Detect sharelink: %d\n", is_share);
229238
#endif /* ENABLE_SHARELINK */

mig/src/libpam-mig/libpam_mig.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -708,27 +708,36 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags,
708708
#ifdef ENABLE_SHARELINK
709709
/* Optional anonymous share link access:
710710
- username must have fixed length matching get_sharelink_length()
711-
- get_sharelink_home()/SHARELINK_SUBDIR/username must exist as a symlink
711+
- get_sharelink_home()/SHARELINK_X_DIR/username must exist as a symlink
712712
- username and password must be identical if we get here (key skips PAM)
713713
*/
714714
WRITELOGMESSAGE(LOG_DEBUG, "Checking for sharelink: %s\n", pUsername);
715715
if (strlen(pUsername) == get_sharelink_length()) {
716716
char share_path[MAX_PATH_LENGTH];
717+
718+
char sharelink_modes[][10] = { SHARELINK_RW_DIR, SHARELINK_RO_DIR, SHARELINK_WO_DIR };
719+
for (size_t i = 0; i < sizeof(sharelink_modes) / sizeof(sharelink_modes[0]); i++)
720+
{
721+
722+
memset(share_path, 0, MAX_PATH_LENGTH);
723+
717724
if (MAX_PATH_LENGTH ==
718725
snprintf(share_path, MAX_PATH_LENGTH, "%s/%s/%s",
719-
get_sharelink_home(), SHARELINK_SUBDIR, pUsername)) {
726+
get_sharelink_home(), sharelink_modes[i], pUsername)) {
720727
WRITELOGMESSAGE(LOG_WARNING,
721728
"Path construction failed for: %s/%s/%s\n",
722-
get_sharelink_home(), SHARELINK_SUBDIR, pUsername);
729+
get_sharelink_home(), sharelink_modes[i], pUsername);
723730
return pam_sm_authenticate_exit(PAM_AUTH_ERR, pwresp);
724731
}
725732
/* NSS lookup assures sharelink target is valid and inside user home */
726733
/* Just check simple access here to make sure it is a share link */
727734
if (access(share_path, R_OK) == 0) {
728735
WRITELOGMESSAGE(LOG_DEBUG,
729-
"Checking sharelink id %s password\n", pUsername);
736+
"Checking %s sharelink id %s password\n", sharelink_modes[i],
737+
pUsername);
730738
if (strcmp(pUsername, pPassword) == 0) {
731-
WRITELOGMESSAGE(LOG_DEBUG, "Return sharelink success\n");
739+
WRITELOGMESSAGE(LOG_DEBUG, "Return %s sharelink success\n",
740+
sharelink_modes[i]);
732741
#ifdef ENABLE_AUTHHANDLER
733742
if (false == mig_reg_auth_attempt(MIG_SKIP_TWOFA_CHECK
734743
| MIG_SKIP_NOTIFY
@@ -759,11 +768,18 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags,
759768
#endif /* ENABLE_AUTHHANDLER */
760769
return pam_sm_authenticate_exit(PAM_AUTH_ERR, pwresp);
761770
}
771+
} else if (i < sizeof(sharelink_modes) - 1) {
772+
WRITELOGMESSAGE(LOG_DEBUG,
773+
"Ignore no match on %s sharelink: %s\n", sharelink_modes[i],
774+
pUsername);
762775
} else {
763776
WRITELOGMESSAGE(LOG_DEBUG,
764777
"No matching sharelink: %s. Try next auth.\n",
765778
share_path);
766779
}
780+
781+
}
782+
767783
} else {
768784
WRITELOGMESSAGE(LOG_DEBUG,
769785
"Not a sharelink username: %s. Try next auth.\n",

0 commit comments

Comments
 (0)