]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
r1888: Bring the same level of "required_membership"-functionality that
authorGünther Deschner <gd@samba.org>
Wed, 18 Aug 2004 16:25:41 +0000 (16:25 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:52:23 +0000 (10:52 -0500)
ntlm_auth uses, to pam_winbindd as well.

This allows to make successfull authentication via PAM dependent on
SID-membership. At the moment, both ntlm_auth and pam_winbindd.so accept
user/group-names or sid-strings - as discussed, recursive membership
(e.g. local aliases) will be added later.

Guenther

source/nsswitch/pam_winbind.c
source/nsswitch/pam_winbind.h

index 123f67036656f423fdbc5930d9e851dd8402d7f2..c98eb4c13912968c427222ad79486739120a5ecc 100644 (file)
@@ -45,6 +45,8 @@ static int _pam_parse(int argc, const char **argv)
                        ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
                else if (!strcasecmp(*argv, "unknown_ok"))
                        ctrl |= WINBIND_UNKNOWN_OK_ARG;
+               else if (!strncasecmp(*argv, "required_membership", strlen("required_membership")))
+                       ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
                else {
                        _pam_log(LOG_ERR, "pam_parse: unknown option; %s", *argv);
                }
@@ -148,7 +150,7 @@ static int pam_winbind_request_log(enum winbindd_cmd req_type,
        switch (retval) {
        case PAM_AUTH_ERR:
                /* incorrect password */
-               _pam_log(LOG_WARNING, "user `%s' denied access (incorrect password)", user);
+               _pam_log(LOG_WARNING, "user `%s' denied access (incorrect password or invalid membership)", user);
                return retval;
        case PAM_ACCT_EXPIRED:
                /* account expired */
@@ -192,7 +194,7 @@ static int pam_winbind_request_log(enum winbindd_cmd req_type,
 }
 
 /* talk to winbindd */
-static int winbind_auth_request(const char *user, const char *pass, int ctrl)
+static int winbind_auth_request(const char *user, const char *pass, const char *member, int ctrl)
 {
        struct winbindd_request request;
        struct winbindd_response response;
@@ -204,7 +206,35 @@ static int winbind_auth_request(const char *user, const char *pass, int ctrl)
 
        strncpy(request.data.auth.pass, pass, 
                 sizeof(request.data.auth.pass)-1);
-       
+
+       if (member == NULL )
+               return pam_winbind_request_log(WINBINDD_PAM_AUTH, &request, &response, ctrl, user);
+
+       /* lookup name? */ 
+       if (!strncmp("S-", member, 2) == 0) {
+               
+               struct winbindd_request request;
+               struct winbindd_response response;
+
+               ZERO_STRUCT(request);
+               ZERO_STRUCT(response)
+
+               if (ctrl & WINBIND_DEBUG_ARG)
+                       _pam_log(LOG_DEBUG, "no sid given, looking up: %s\n", member);
+
+               /* fortunatly winbindd can handle non-separated names */
+               strcpy(request.data.name.name, member);
+
+               if (pam_winbind_request_log(WINBINDD_LOOKUPNAME, &request, &response, ctrl, user)) {
+                       _pam_log(LOG_INFO, "could not lookup name: %s\n", member); 
+                       return PAM_AUTH_ERR;
+               }
+
+               member = strdup(response.data.sid.sid);
+       }
+
+       strncpy(request.data.auth.required_membership_sid, member, 
+               sizeof(request.data.auth.required_membership_sid)-1);
        
         return pam_winbind_request_log(WINBINDD_PAM_AUTH, &request, &response, ctrl, user);
 }
@@ -419,6 +449,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
 {
      const char *username;
      const char *password;
+     const char *member = NULL;
      int retval = PAM_AUTH_ERR;
     
      /* parse arguments */
@@ -453,8 +484,26 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
 #endif
      }
 
+     /* Retrieve membership-string here */
+     int i;
+     for ( i=0; i<argc; i++ ) {
+
+        if (!strncmp(argv[i], "required_membership", strlen("required_membership"))) {
+
+            char *p;
+            char *parm = strdup(argv[i]);
+
+            if ( (p = strchr( parm, '=' )) == NULL) {
+               _pam_log(LOG_INFO, "no \"=\" delimiter for \"required_membership\" found\n");
+               break;
+            }
+
+            member = strdup(p+1);
+        }
+     }
+
      /* Now use the username to look up password */
-     return winbind_auth_request(username, password, ctrl);
+     return winbind_auth_request(username, password, member, ctrl);
 }
 
 PAM_EXTERN
@@ -546,6 +595,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 
        /* <DO NOT free() THESE> */
        const char *user;
+       const char *member = NULL;
        char *pass_old, *pass_new;
        /* </DO NOT free() THESE> */
 
@@ -606,7 +656,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                }
                /* verify that this is the password for this user */
                
-               retval = winbind_auth_request(user, pass_old, ctrl);
+               retval = winbind_auth_request(user, pass_old, member, ctrl);
                
                if (retval != PAM_ACCT_EXPIRED 
                    && retval != PAM_AUTHTOK_EXPIRED
index 0afcceb6aa2e8d01bd8572e78ee179ea9ed97e1a..7cae477714bd42bc043e8201c9dadd2ac8bef6e2 100644 (file)
@@ -82,6 +82,7 @@ do {                             \
 #define WINBIND_TRY_FIRST_PASS_ARG (1<<3)
 #define WINBIND_USE_FIRST_PASS_ARG (1<<4)
 #define WINBIND__OLD_PASSWORD (1<<5)
+#define WINBIND_REQUIRED_MEMBERSHIP (1<<6)
 
 /*
  * here is the string to inform the user that the new passwords they