Don't fill password policy structure for any domain other than our own.
[ira/wip.git] / source3 / winbindd / winbindd_pam.c
index 79b4c764c3784b4af327fe01b7b2fef10621f666..3b13a9269a960f8683b09704b3eeda7a0fb48b07 100644 (file)
@@ -27,6 +27,8 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
+#define LOGON_KRB5_FAIL_CLOCK_SKEW     0x02000000
+
 static NTSTATUS append_info3_as_txt(TALLOC_CTX *mem_ctx,
                                    struct winbindd_cli_state *state,
                                    struct netr_SamInfo3 *info3)
@@ -157,7 +159,6 @@ static NTSTATUS append_unix_username(TALLOC_CTX *mem_ctx,
        /* We've been asked to return the unix username, per
           'winbind use default domain' settings and the like */
 
-       fstring username_out;
        const char *nt_username, *nt_domain;
 
        nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
@@ -174,18 +175,11 @@ static NTSTATUS append_unix_username(TALLOC_CTX *mem_ctx,
                nt_username = name_user;
        }
 
-       fill_domain_username(username_out, nt_domain, nt_username,
-                            True);
-
-       DEBUG(5,("Setting unix username to [%s]\n", username_out));
+       fill_domain_username(state->response.data.auth.unix_username,
+                            nt_domain, nt_username, True);
 
-       SAFE_FREE(state->response.extra_data.data);
-       state->response.extra_data.data = SMB_STRDUP(username_out);
-       if (!state->response.extra_data.data) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       state->response.length +=
-               strlen((const char *)state->response.extra_data.data)+1;
+       DEBUG(5,("Setting unix username to [%s]\n",
+               state->response.data.auth.unix_username));
 
        return NT_STATUS_OK;
 }
@@ -736,14 +730,12 @@ failed:
 static bool check_request_flags(uint32_t flags)
 {
        uint32_t flags_edata = WBFLAG_PAM_AFS_TOKEN |
-                              WBFLAG_PAM_UNIX_NAME |
                               WBFLAG_PAM_INFO3_TEXT |
                               WBFLAG_PAM_INFO3_NDR;
 
        if ( ( (flags & flags_edata) == WBFLAG_PAM_AFS_TOKEN) ||
             ( (flags & flags_edata) == WBFLAG_PAM_INFO3_NDR) ||
             ( (flags & flags_edata) == WBFLAG_PAM_INFO3_TEXT)||
-            ( (flags & flags_edata) == WBFLAG_PAM_UNIX_NAME) ||
              !(flags & flags_edata) ) {
                return True;
        }
@@ -1293,6 +1285,17 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
        /* check authentication loop */
 
        do {
+               NTSTATUS (*logon_fn)(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx,
+                                    uint32 logon_parameters,
+                                    const char *server,
+                                    const char *username,
+                                    const char *domain,
+                                    const char *workstation,
+                                    const uint8 chal[8],
+                                    DATA_BLOB lm_response,
+                                    DATA_BLOB nt_response,
+                                    struct netr_SamInfo3 **info3);
 
                ZERO_STRUCTP(my_info3);
                retry = False;
@@ -1304,19 +1307,32 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
                        goto done;
                }
 
-               result = rpccli_netlogon_sam_network_logon(netlogon_pipe,
-                                                          state->mem_ctx,
-                                                          0,
-                                                          contact_domain->dcname, /* server name */
-                                                          name_user,              /* user name */
-                                                          name_domain,            /* target domain */
-                                                          global_myname(),        /* workstation */
-                                                          chal,
-                                                          lm_resp,
-                                                          nt_resp,
-                                                          &my_info3);
+               logon_fn = contact_domain->can_do_samlogon_ex
+                       ? rpccli_netlogon_sam_network_logon_ex
+                       : rpccli_netlogon_sam_network_logon;
+
+               result = logon_fn(netlogon_pipe,
+                                 state->mem_ctx,
+                                 0,
+                                 contact_domain->dcname, /* server name */
+                                 name_user,              /* user name */
+                                 name_domain,            /* target domain */
+                                 global_myname(),        /* workstation */
+                                 chal,
+                                 lm_resp,
+                                 nt_resp,
+                                 &my_info3);
                attempts += 1;
 
+               if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
+                   && contact_domain->can_do_samlogon_ex) {
+                       DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
+                                 "retrying with NetSamLogon\n"));
+                       contact_domain->can_do_samlogon_ex = False;
+                       retry = True;
+                       continue;
+               }
+
                /* We have to try a second time as cm_connect_netlogon
                   might not yet have noticed that the DC has killed
                   our connection. */
@@ -1348,7 +1364,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
         * caller, we look up the account flags ourselve - gd */
 
        if ((state->request.flags & WBFLAG_PAM_INFO3_TEXT) && 
-           (my_info3->base.acct_flags == 0) && NT_STATUS_IS_OK(result)) {
+           NT_STATUS_IS_OK(result) && (my_info3->base.acct_flags == 0)) {
 
                struct rpc_pipe_client *samr_pipe;
                POLICY_HND samr_domain_handle, user_pol;
@@ -1622,12 +1638,24 @@ process_result:
 
 
                if (state->request.flags & WBFLAG_PAM_GET_PWD_POLICY) {
-                       result = fillup_password_policy(domain, state);
-
+                       struct winbindd_domain *our_domain = find_our_domain();
+                       
+                       /* This is not entiurely correct I believe, but it is 
+                          consistent.  Only apply the password policy settings
+                          too warn users for our own domain.  Cannot obtain these 
+                          from trusted DCs all the  time so don't do it at all. 
+                          -- jerry */
+
+                       result = NT_STATUS_NOT_SUPPORTED;                       
+                       if (our_domain == domain ) {
+a                              result = fillup_password_policy(our_domain, state);
+                       }
+                       
                        if (!NT_STATUS_IS_OK(result) 
                            && !NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) ) 
                        {
-                               DEBUG(10,("Failed to get password policies: %s\n", nt_errstr(result)));
+                               DEBUG(10,("Failed to get password policies for domain %s: %s\n", 
+                                         domain->name, nt_errstr(result)));
                                goto done;
                        }
                }
@@ -1814,6 +1842,18 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
        }
 
        do {
+               NTSTATUS (*logon_fn)(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx,
+                                    uint32 logon_parameters,
+                                    const char *server,
+                                    const char *username,
+                                    const char *domain,
+                                    const char *workstation,
+                                    const uint8 chal[8],
+                                    DATA_BLOB lm_response,
+                                    DATA_BLOB nt_response,
+                                    struct netr_SamInfo3 **info3);
+
                retry = False;
 
                netlogon_pipe = NULL;
@@ -1825,18 +1865,31 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
                        goto done;
                }
 
-               result = rpccli_netlogon_sam_network_logon(netlogon_pipe,
-                                                          state->mem_ctx,
-                                                          state->request.data.auth_crap.logon_parameters,
-                                                          contact_domain->dcname,
-                                                          name_user,
-                                                          name_domain, 
-                                                                       /* Bug #3248 - found by Stefan Burkei. */
-                                                          workstation, /* We carefully set this above so use it... */
-                                                          state->request.data.auth_crap.chal,
-                                                          lm_resp,
-                                                          nt_resp,
-                                                          &info3);
+               logon_fn = contact_domain->can_do_samlogon_ex
+                       ? rpccli_netlogon_sam_network_logon_ex
+                       : rpccli_netlogon_sam_network_logon;
+
+               result = logon_fn(netlogon_pipe,
+                                 state->mem_ctx,
+                                 state->request.data.auth_crap.logon_parameters,
+                                 contact_domain->dcname,
+                                 name_user,
+                                 name_domain, 
+                                 /* Bug #3248 - found by Stefan Burkei. */
+                                 workstation, /* We carefully set this above so use it... */
+                                 state->request.data.auth_crap.chal,
+                                 lm_resp,
+                                 nt_resp,
+                                 &info3);
+
+               if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
+                   && contact_domain->can_do_samlogon_ex) {
+                       DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
+                                 "retrying with NetSamLogon\n"));
+                       contact_domain->can_do_samlogon_ex = False;
+                       retry = True;
+                       continue;
+               }
 
                attempts += 1;