Merge branch 'master' of ssh://jra@git.samba.org/data/git/samba
[sfrench/samba-autobuild/.git] / source3 / winbindd / winbindd_pam.c
index b379e2c7a942ec94914c4c8bd95263225cc3f54e..fe6485522e083f8ac1b32cb381b8c1f8a47105fe 100644 (file)
@@ -231,9 +231,8 @@ static NTSTATUS append_afs_token(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
-                                    struct netr_SamInfo3 *info3,
-                                    const char *group_sid)
+NTSTATUS check_info3_in_group(struct netr_SamInfo3 *info3,
+                             const char *group_sid)
 /**
  * Check whether a user belongs to a group or list of groups.
  *
@@ -253,7 +252,7 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
        DOM_SID sid;
        size_t i;
        struct nt_user_token *token;
-       TALLOC_CTX *frame = NULL;
+       TALLOC_CTX *frame = talloc_stackframe();
        NTSTATUS status;
 
        /* Parse the 'required group' SID */
@@ -263,8 +262,10 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
                return NT_STATUS_OK;
        }
 
-       if (!(token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token))) {
+       token = talloc_zero(talloc_tos(), struct nt_user_token);
+       if (token == NULL) {
                DEBUG(0, ("talloc failed\n"));
+               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -273,8 +274,7 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
 
        p = group_sid;
 
-       frame = talloc_stackframe();
-       while (next_token_talloc(frame, &p, &req_sid, ",")) {
+       while (next_token_talloc(talloc_tos(), &p, &req_sid, ",")) {
                if (!string_to_sid(&sid, req_sid)) {
                        DEBUG(0, ("check_info3_in_group: could not parse %s "
                                  "as a SID!", req_sid));
@@ -282,7 +282,7 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
                        return NT_STATUS_INVALID_PARAMETER;
                }
 
-               status = add_sid_to_array(mem_ctx, &sid,
+               status = add_sid_to_array(talloc_tos(), &sid,
                                          &require_membership_of_sid,
                                          &num_require_membership_of_sid);
                if (!NT_STATUS_IS_OK(status)) {
@@ -292,13 +292,12 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
                }
        }
 
-       TALLOC_FREE(frame);
-
-       status = sid_array_from_info3(mem_ctx, info3,
+       status = sid_array_from_info3(talloc_tos(), info3,
                                      &token->user_sids,
                                      &token->num_sids,
                                      true, false);
        if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
                return status;
        }
 
@@ -308,6 +307,7 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
                                                     token))) {
                DEBUG(3, ("could not add aliases: %s\n",
                          nt_errstr(status)));
+               TALLOC_FREE(frame);
                return status;
        }
 
@@ -319,12 +319,14 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
                if (nt_token_check_sid(&require_membership_of_sid[i],
                                       token)) {
                        DEBUG(10, ("Access ok\n"));
+                       TALLOC_FREE(frame);
                        return NT_STATUS_OK;
                }
        }
 
        /* Do not distinguish this error from a wrong username/pw */
 
+       TALLOC_FREE(frame);
        return NT_STATUS_LOGON_FAILURE;
 }
 
@@ -522,7 +524,7 @@ static void setup_return_cc_name(struct winbindd_cli_state *state, const char *c
 
 static uid_t get_uid_from_state(struct winbindd_cli_state *state)
 {
-       uid_t uid = -1;
+       uid_t uid;
 
        uid = state->request->data.auth.uid;
 
@@ -705,7 +707,7 @@ failed:
 /****************************************************************
 ****************************************************************/
 
-static bool check_request_flags(uint32_t flags)
+bool check_request_flags(uint32_t flags)
 {
        uint32_t flags_edata = WBFLAG_PAM_AFS_TOKEN |
                               WBFLAG_PAM_INFO3_TEXT |
@@ -718,7 +720,8 @@ static bool check_request_flags(uint32_t flags)
                return true;
        }
 
-       DEBUG(1,("check_request_flags: invalid request flags[0x%08X]\n",flags));
+       DEBUG(1, ("check_request_flags: invalid request flags[0x%08X]\n",
+                 flags));
 
        return false;
 }
@@ -794,8 +797,8 @@ NTSTATUS append_auth_data(struct winbindd_cli_state *state,
 void winbindd_pam_auth(struct winbindd_cli_state *state)
 {
        struct winbindd_domain *domain;
-       fstring name_domain, name_user;
-       char *mapped_user = NULL;
+       fstring name_domain, name_user, mapped_user;
+       char *mapped = NULL;
        NTSTATUS result;
        NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
 
@@ -819,15 +822,16 @@ void winbindd_pam_auth(struct winbindd_cli_state *state)
 
        name_map_status = normalize_name_unmap(state->mem_ctx,
                                               state->request->data.auth.user,
-                                              &mapped_user);
+                                              &mapped);
 
        /* If the name normalization didnt' actually do anything,
           just use the original name */
 
-       if (!NT_STATUS_IS_OK(name_map_status) &&
-           !NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
-       {
-               mapped_user = state->request->data.auth.user;
+       if (NT_STATUS_IS_OK(name_map_status)
+           ||NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) {
+               fstrcpy(mapped_user, mapped);
+       } else {
+               fstrcpy(mapped_user, state->request->data.auth.user);
        }
 
        if (!canonicalize_username(mapped_user, name_domain, name_user)) {
@@ -1627,8 +1631,10 @@ process_result:
 
                /* Check if the user is in the right group */
 
-               if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, info3,
-                                       state->request->data.auth.require_membership_of_sid))) {
+               result = check_info3_in_group(
+                       info3,
+                       state->request->data.auth.require_membership_of_sid);
+               if (!NT_STATUS_IS_OK(result)) {
                        DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n",
                                  state->request->data.auth.user,
                                  state->request->data.auth.require_membership_of_sid));
@@ -1951,8 +1957,10 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
 
                /* Check if the user is in the right group */
 
-               if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, info3,
-                                                       state->request->data.auth_crap.require_membership_of_sid))) {
+               result = check_info3_in_group(
+                       info3,
+                       state->request->data.auth_crap.require_membership_of_sid);
+               if (!NT_STATUS_IS_OK(result)) {
                        DEBUG(3, ("User %s is not in the required group (%s), so "
                                  "crap authentication is rejected\n",
                                  state->request->data.auth_crap.user,
@@ -2053,7 +2061,7 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
        struct rpc_pipe_client *cli;
        bool got_info = false;
        struct samr_DomInfo1 *info = NULL;
-       struct samr_ChangeReject *reject = NULL;
+       struct userPwdChangeFailureInformation *reject = NULL;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        fstring domain, user;
 
@@ -2095,7 +2103,7 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
                fill_in_password_policy(state->response, info);
 
                state->response->data.auth.reject_reason =
-                       reject->reason;
+                       reject->extendedFailureReason;
 
                got_info = true;
        }