diff options
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/wb_client.c | 70 | ||||
-rw-r--r-- | source3/nsswitch/wb_common.c | 16 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 26 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_nss.h | 13 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_pam.c | 63 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_passdb.c | 4 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_sid.c | 30 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_user.c | 23 |
8 files changed, 179 insertions, 66 deletions
diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c index 196e44020c..67548592b2 100644 --- a/source3/nsswitch/wb_client.c +++ b/source3/nsswitch/wb_client.c @@ -168,6 +168,41 @@ BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid) return (result == NSS_STATUS_SUCCESS); } +/* Call winbindd to convert SID to uid. Do not allocate */ + +BOOL winbind_sid_to_uid_query(uid_t *puid, const DOM_SID *sid) +{ + struct winbindd_request request; + struct winbindd_response response; + int result; + fstring sid_str; + + if (!puid) + return False; + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + sid_to_string(sid_str, sid); + fstrcpy(request.data.sid, sid_str); + + request.flags = WBFLAG_QUERY_ONLY; + + /* Make request */ + + result = winbindd_request(WINBINDD_SID_TO_UID, &request, &response); + + /* Copy out result */ + + if (result == NSS_STATUS_SUCCESS) { + *puid = response.data.uid; + } + + return (result == NSS_STATUS_SUCCESS); +} + /* Call winbindd to convert SID to gid */ BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid) @@ -201,6 +236,41 @@ BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid) return (result == NSS_STATUS_SUCCESS); } +/* Call winbindd to convert SID to gid. Do not allocate */ + +BOOL winbind_sid_to_gid_query(gid_t *pgid, const DOM_SID *sid) +{ + struct winbindd_request request; + struct winbindd_response response; + int result; + fstring sid_str; + + if (!pgid) + return False; + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + sid_to_string(sid_str, sid); + fstrcpy(request.data.sid, sid_str); + + request.flags = WBFLAG_QUERY_ONLY; + + /* Make request */ + + result = winbindd_request(WINBINDD_SID_TO_GID, &request, &response); + + /* Copy out result */ + + if (result == NSS_STATUS_SUCCESS) { + *pgid = response.data.gid; + } + + return (result == NSS_STATUS_SUCCESS); +} + /* Call winbindd to convert gid to sid */ BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c index adcfdaa9d8..acaf0ed17c 100644 --- a/source3/nsswitch/wb_common.c +++ b/source3/nsswitch/wb_common.c @@ -468,3 +468,19 @@ NSS_STATUS winbindd_request(int req_type, return(status); return winbindd_get_response(response); } + +/************************************************************************* + A couple of simple jfunctions to disable winbindd lookups and re- + enable them + ************************************************************************/ + +BOOL winbind_off( void ) +{ + return (setenv( WINBINDD_DONT_ENV, "1", 1 ) != -1); +} + +BOOL winbind_on( void ) +{ + return (setenv( WINBINDD_DONT_ENV, "0", 1 ) != -1); +} + diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 70c8de6ee9..9a969abeaa 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -214,10 +214,11 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) if (!parse_domain_user(tmp, name_domain, name_group)) return WINBINDD_ERROR; - /* don't handle our own domain if we are a DC. This code handles cases where + /* don't handle our own domain if we are a DC ( or a member of a Samba domain + that shares UNIX accounts). This code handles cases where the account doesn't exist anywhere and gets passed on down the NSS layer */ - if ( IS_DC_FOR_DOMAIN(domain->name) ) { + if ( (IS_DC || lp_winbind_trusted_domains_only()) && strequal(name_domain, lp_workgroup()) ) { DEBUG(7,("winbindd_getgrnam: rejecting getpwnam() for %s\\%s since I am on the PDC for this domain\n", name_domain, name_group)); return WINBINDD_ERROR; @@ -248,7 +249,7 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid))) { + if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &gid, 0))) { DEBUG(1, ("error converting unix gid to sid\n")); return WINBINDD_ERROR; } @@ -293,7 +294,7 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) return WINBINDD_ERROR; /* Get rid from gid */ - if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, state->request.data.gid))) { + if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&group_sid, state->request.data.gid))) { DEBUG(1, ("could not convert gid %d to rid\n", state->request.data.gid)); return WINBINDD_ERROR; @@ -370,10 +371,14 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) struct getent_state *domain_state; - /* don't add our domaina if we are a PDC */ + /* don't add our domaina if we are a PDC or if we + are a member of a Samba domain */ - if ( IS_DC_FOR_DOMAIN(domain->name) ) + if ( (IS_DC || lp_winbind_trusted_domains_only()) + && strequal(domain->name, lp_workgroup()) ) + { continue; + } /* Create a state record for this domain */ @@ -612,7 +617,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) sid_copy(&group_sid, &domain->sid); sid_append_rid(&group_sid, name_list[ent->sam_entry_index].rid); - if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &group_gid))) { + if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &group_gid, 0))) { DEBUG(1, ("could not look up gid for group %s\n", name_list[ent->sam_entry_index].acct_name)); @@ -925,8 +930,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) /* Map to a gid */ - if (!NT_STATUS_IS_OK(sid_to_gid(&info3->other_sids[i].sid, - &gid_list[num_gids])) ) + if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&info3->other_sids[i].sid, &gid_list[num_gids], 0)) ) { DEBUG(10, ("winbindd_getgroups: could not map sid %s to gid\n", sid_string_static(&info3->other_sids[i].sid))); @@ -950,7 +954,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) sid_copy( &group_sid, &domain->sid ); sid_append_rid( &group_sid, info3->gids[i].g_rid ); - if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid_list[num_gids])) ) { + if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &gid_list[num_gids], 0)) ) { DEBUG(10, ("winbindd_getgroups: could not map sid %s to gid\n", sid_string_static(&group_sid))); } @@ -973,7 +977,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; for (i = 0; i < num_groups; i++) { - if (!NT_STATUS_IS_OK(sid_to_gid(user_grpsids[i], &gid_list[num_gids]))) { + if (!NT_STATUS_IS_OK(idmap_sid_to_gid(user_grpsids[i], &gid_list[num_gids], 0))) { DEBUG(1, ("unable to convert group sid %s to gid\n", sid_string_static(user_grpsids[i]))); continue; diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index cc1b144063..1ddfb2174e 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -111,11 +111,12 @@ enum winbindd_cmd { WINBINDD_NUM_CMDS }; -#define WINBIND_PAM_INFO3_NDR 0x0001 -#define WINBIND_PAM_INFO3_TEXT 0x0002 -#define WINBIND_PAM_NTKEY 0x0004 -#define WINBIND_PAM_LMKEY 0x0008 -#define WINBIND_PAM_CONTACT_TRUSTDOM 0x0010 +#define WBFLAG_PAM_INFO3_NDR 0x0001 +#define WBFLAG_PAM_INFO3_TEXT 0x0002 +#define WBFLAG_PAM_NTKEY 0x0004 +#define WBFLAG_PAM_LMKEY 0x0008 +#define WBFLAG_PAM_CONTACT_TRUSTDOM 0x0010 +#define WBFLAG_QUERY_ONLY 0x0020 /* Winbind request structure */ @@ -123,6 +124,7 @@ struct winbindd_request { uint32 length; enum winbindd_cmd cmd; /* Winbindd command to execute */ pid_t pid; /* pid of calling process */ + uint32 flags; /* flags relavant to a given request */ union { fstring winsreq; /* WINS request */ @@ -146,7 +148,6 @@ struct winbindd_request { fstring nt_resp; uint16 nt_resp_len; fstring workstation; - uint32 flags; } auth_crap; struct { fstring user; diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 75e10eb405..6aaf3bc715 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -63,41 +63,38 @@ static BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16], DOM_SID sid; char *pwd; - if ( lp_server_role()==ROLE_DOMAIN_MEMBER || strequal(domain, lp_workgroup()) ) + /* if we are a DC and this is not our domain, then lookup an account + for the domain trust */ + + if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() ) { - /* - * Get the machine account password for the domain to contact. - * This is either our own domain for a workstation, or possibly - * any domain for a PDC with trusted domains. - */ - - if ( !secrets_fetch_trust_account_password (domain, ret_pwd, - pass_last_set_time, channel) ) + if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid, + pass_last_set_time) ) { DEBUG(0, ("get_trust_pw: could not fetch trust account " - "password for my domain %s\n", domain)); + "password for trusted domain %s\n", domain)); return False; } + *channel = SEC_CHAN_DOMAIN; + E_md4hash(pwd, ret_pwd); + SAFE_FREE(pwd); + return True; } - else if ( lp_allow_trusted_domains() ) + else /* just get the account for our domain (covers + ROLE_DOMAIN_MEMBER as well */ { - /* if we are not a domain member, then we must be a DC and - this must be a trusted domain */ + /* get the machine trust account for our domain */ - if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid, - pass_last_set_time) ) + if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd, + pass_last_set_time, channel) ) { DEBUG(0, ("get_trust_pw: could not fetch trust account " - "password for trusted domain %s\n", domain)); + "password for my domain %s\n", domain)); return False; } - *channel = SEC_CHAN_DOMAIN; - E_md4hash(pwd, ret_pwd); - SAFE_FREE(pwd); - return True; } @@ -126,6 +123,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) int attempts = 0; unsigned char local_lm_response[24]; unsigned char local_nt_response[24]; + const char *contact_domain; /* Ensure null termination */ state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0'; @@ -166,6 +164,13 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) goto done; } + /* what domain should we contact? */ + + if ( IS_DC ) + contact_domain = name_domain; + else + contact_domain = lp_workgroup(); + /* check authentication loop */ do { @@ -173,7 +178,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) ZERO_STRUCT(ret_creds); /* Don't shut this down - it belongs to the connection cache code */ - result = cm_get_netlogon_cli(name_domain, trust_passwd, + result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, False, &cli); if (!NT_STATUS_IS_OK(result)) { @@ -255,6 +260,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) char *user = NULL; const char *domain = NULL; const char *workstation; + const char *contact_domain; DOM_CRED ret_creds; int attempts = 0; @@ -329,12 +335,19 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) lm_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len); nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len); + /* what domain should we contact? */ + + if ( IS_DC ) + contact_domain = domain; + else + contact_domain = lp_workgroup(); + do { ZERO_STRUCT(info3); ZERO_STRUCT(ret_creds); /* Don't shut this down - it belongs to the connection cache code */ - result = cm_get_netlogon_cli(domain, trust_passwd, sec_channel_type, False, &cli); + result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, False, &cli); if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", @@ -376,14 +389,14 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) netsamlogon_cache_store( cli->mem_ctx, &info3 ); wcache_invalidate_samlogon(find_domain_from_name(domain), &info3); - if (state->request.data.auth_crap.flags & WINBIND_PAM_INFO3_NDR) { + if (state->request.flags & WBFLAG_PAM_INFO3_NDR) { result = append_info3_as_ndr(mem_ctx, state, &info3); } - if (state->request.data.auth_crap.flags & WINBIND_PAM_NTKEY) { + if (state->request.flags & WBFLAG_PAM_NTKEY) { memcpy(state->response.data.auth.nt_session_key, info3.user_sess_key, sizeof(state->response.data.auth.nt_session_key) /* 16 */); } - if (state->request.data.auth_crap.flags & WINBIND_PAM_LMKEY) { + if (state->request.flags & WBFLAG_PAM_LMKEY) { memcpy(state->response.data.auth.first_8_lm_hash, info3.padding, sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */); } } diff --git a/source3/nsswitch/winbindd_passdb.c b/source3/nsswitch/winbindd_passdb.c index 401662b6a7..456b1afeab 100644 --- a/source3/nsswitch/winbindd_passdb.c +++ b/source3/nsswitch/winbindd_passdb.c @@ -175,7 +175,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, DEBUG(3,("pdb: sid_to_name sid=%s\n", sid_string_static(sid))); - if (NT_STATUS_IS_OK(sid_to_uid(sid, &id))) { /* this is a user */ + if (NT_STATUS_IS_OK(idmap_sid_to_uid(sid, &id, 0))) { /* this is a user */ if (!NT_STATUS_IS_OK(result = pdb_init_sam(&sam_account))) { return result; @@ -197,7 +197,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, *type = SID_NAME_USER; result = NT_STATUS_OK; - } else if (NT_STATUS_IS_OK(sid_to_gid(sid, &id))) { /* this is a group */ + } else if (NT_STATUS_IS_OK(idmap_sid_to_gid(sid, &id, 0))) { /* this is a group */ DEBUG(3,("pdb: sid_to_name: group support not implemented\n")); result = NT_STATUS_UNSUCCESSFUL; diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index 5d7741850c..676beae3aa 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -122,6 +122,7 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) { DOM_SID sid; + uint32 flags = 0x0; /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; @@ -131,15 +132,16 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) /* Split sid into domain sid and user rid */ if (!string_to_sid(&sid, state->request.data.sid)) { - DEBUG(1, ("Could not get convert sid %s from string\n", - state->request.data.sid)); + DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid)); return WINBINDD_ERROR; } - + + if ( state->request.flags & WBFLAG_QUERY_ONLY ) + flags = ID_QUERY_ONLY; + /* Find uid for this sid and return it */ - if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &(state->response.data.uid)))) { - DEBUG(1, ("Could not get uid for sid %s\n", - state->request.data.sid)); + if ( !NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) ) { + DEBUG(1, ("Could not get uid for sid %s\n", state->request.data.sid)); return WINBINDD_ERROR; } @@ -152,6 +154,7 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) { DOM_SID sid; + uint32 flags = 0x0; /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; @@ -160,15 +163,16 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) state->request.data.sid)); if (!string_to_sid(&sid, state->request.data.sid)) { - DEBUG(1, ("Could not cvt string to sid %s\n", - state->request.data.sid)); + DEBUG(1, ("Could not cvt string to sid %s\n", state->request.data.sid)); return WINBINDD_ERROR; } + if ( state->request.flags & WBFLAG_QUERY_ONLY ) + flags = ID_QUERY_ONLY; + /* Find gid for this sid and return it */ - if (!NT_STATUS_IS_OK(sid_to_gid(&sid, &(state->response.data.gid)))) { - DEBUG(1, ("Could not get gid for sid %s\n", - state->request.data.sid)); + if ( !NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) ) { + DEBUG(1, ("Could not get gid for sid %s\n", state->request.data.sid)); return WINBINDD_ERROR; } @@ -192,7 +196,7 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) state->request.data.uid)); /* Lookup rid for this uid */ - if (!NT_STATUS_IS_OK(uid_to_sid(&sid, state->request.data.uid))) { + if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid))) { DEBUG(1, ("Could not convert uid %d to rid\n", state->request.data.uid)); return WINBINDD_ERROR; @@ -221,7 +225,7 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) state->request.data.gid)); /* Lookup sid for this uid */ - if (!NT_STATUS_IS_OK(gid_to_sid(&sid, state->request.data.gid))) { + if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid))) { DEBUG(1, ("Could not convert gid %d to sid\n", state->request.data.gid)); return WINBINDD_ERROR; diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index 9d9360a6fa..37d9245075 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -44,14 +44,14 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, /* Resolve the uid number */ - if (!NT_STATUS_IS_OK(sid_to_uid(user_sid, &(pw->pw_uid)))) { + if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &(pw->pw_uid), 0))) { DEBUG(1, ("error getting user id for sid %s\n", sid_to_string(sid_string, user_sid))); return False; } /* Resolve the gid number */ - if (!NT_STATUS_IS_OK(sid_to_gid(group_sid, &(pw->pw_gid)))) { + if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &(pw->pw_gid), 0))) { DEBUG(1, ("error getting group id for sid %s\n", sid_to_string(sid_string, group_sid))); return False; } @@ -116,10 +116,11 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) name_user)) return WINBINDD_ERROR; - /* don't handle our own domain if we are a DC. This code handles cases where + /* don't handle our own domain if we are a DC ( or a member of a Samba domain + that shares UNIX accounts). This code handles cases where the account doesn't exist anywhere and gets passed on down the NSS layer */ - if ( IS_DC_FOR_DOMAIN(domain->name) ) { + if ( (IS_DC || lp_winbind_trusted_domains_only()) && strequal(name_domain, lp_workgroup()) ) { DEBUG(7,("winbindd_getpwnam: rejecting getpwnam() for %s\\%s since I am on the PDC for this domain\n", name_domain, name_user)); return WINBINDD_ERROR; @@ -202,7 +203,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) /* Get rid from uid */ - if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, state->request.data.uid))) { + if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&user_sid, state->request.data.uid))) { DEBUG(1, ("could not convert uid %d to SID\n", state->request.data.uid)); return WINBINDD_ERROR; @@ -246,7 +247,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) /* Check group has a gid number */ - if (!NT_STATUS_IS_OK(sid_to_gid(user_info.group_sid, &gid))) { + if (!NT_STATUS_IS_OK(idmap_sid_to_gid(user_info.group_sid, &gid, 0))) { DEBUG(1, ("error getting group id for user %s\n", user_name)); talloc_destroy(mem_ctx); return WINBINDD_ERROR; @@ -296,10 +297,14 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state) struct getent_state *domain_state; - /* don't add our domaina if we are a PDC */ + /* don't add our domaina if we are a PDC or if we + are a member of a Samba domain */ - if ( IS_DC_FOR_DOMAIN( domain->name ) ) - continue; + if ( (IS_DC || lp_winbind_trusted_domains_only()) + && strequal(domain->name, lp_workgroup()) ) + { + continue; + } /* Create a state record for this domain */ |