diff options
author | Gerald Carter <jerry@samba.org> | 2006-02-23 16:28:33 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2006-02-23 16:28:33 +0000 |
commit | 13867f26d15f7724a36227b2e4066a9b5575d171 (patch) | |
tree | 9bbea61ba35cc8a79580cf36fb27badd50f9f660 | |
parent | eddeae3a80ed231720d0ee5bd22bd1012e5be674 (diff) | |
download | samba-13867f26d15f7724a36227b2e4066a9b5575d171.tar.gz |
r13659: Pulling in what I think are the final code changes for 3.0.21c
svn merge -r13639:13641 $SVNURL/branches/SAMBA_3_0
svn merge -r13645:13647 $SVNURL/branches/SAMBA_3_0
svn merge -r13656:13657 $SVNURL/branches/SAMBA_3_0
-rw-r--r-- | source/include/ads.h | 2 | ||||
-rw-r--r-- | source/libads/ads_struct.c | 1 | ||||
-rw-r--r-- | source/libads/ldap.c | 7 | ||||
-rw-r--r-- | source/nsswitch/winbindd_ads.c | 36 | ||||
-rw-r--r-- | source/rpc_client/cli_pipe.c | 22 | ||||
-rw-r--r-- | source/smbd/negprot.c | 19 | ||||
-rw-r--r-- | source/utils/net_rpc_join.c | 52 |
7 files changed, 105 insertions, 34 deletions
diff --git a/source/include/ads.h b/source/include/ads.h index decb823ea99..82a413a72b6 100644 --- a/source/include/ads.h +++ b/source/include/ads.h @@ -47,6 +47,7 @@ typedef struct { char *sfu_shell_attr; char *sfu_uidnumber_attr; char *sfu_gidnumber_attr; + char *sfu_gecos_attr; } schema; } ADS_STRUCT; @@ -97,6 +98,7 @@ typedef void **ADS_MODLIST; #define ADS_ATTR_SFU_GIDNUMBER_OID "1.2.840.113556.1.6.18.1.311" #define ADS_ATTR_SFU_HOMEDIR_OID "1.2.840.113556.1.6.18.1.344" #define ADS_ATTR_SFU_SHELL_OID "1.2.840.113556.1.6.18.1.312" +#define ADS_ATTR_SFU_GECOS_OID "1.2.840.113556.1.6.18.1.337" /* ldap bitwise searches */ #define ADS_LDAP_MATCHING_RULE_BIT_AND "1.2.840.113556.1.4.803" diff --git a/source/libads/ads_struct.c b/source/libads/ads_struct.c index d8676d050dd..9b2179ad316 100644 --- a/source/libads/ads_struct.c +++ b/source/libads/ads_struct.c @@ -139,6 +139,7 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->schema.sfu_gidnumber_attr); SAFE_FREE((*ads)->schema.sfu_shell_attr); SAFE_FREE((*ads)->schema.sfu_homedir_attr); + SAFE_FREE((*ads)->schema.sfu_gecos_attr); ZERO_STRUCTP(*ads); diff --git a/source/libads/ldap.c b/source/libads/ldap.c index dc93bd556c7..4479568f5dc 100644 --- a/source/libads/ldap.c +++ b/source/libads/ldap.c @@ -2563,7 +2563,7 @@ BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) { BOOL ret = False; TALLOC_CTX *ctx = NULL; - const char *gidnumber, *uidnumber, *homedir, *shell; + const char *gidnumber, *uidnumber, *homedir, *shell, *gecos; ctx = talloc_init("ads_check_sfu_mapping"); if (ctx == NULL) @@ -2589,6 +2589,11 @@ BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) goto done; ads->schema.sfu_shell_attr = SMB_STRDUP(shell); + gecos = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GECOS_OID); + if (gecos == NULL) + goto done; + ads->schema.sfu_gecos_attr = SMB_STRDUP(gecos); + ret = True; done: if (ctx) diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c index 29129e823a2..b6e6c507327 100644 --- a/source/nsswitch/winbindd_ads.c +++ b/source/nsswitch/winbindd_ads.c @@ -151,7 +151,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, "name", "objectSid", "primaryGroupID", "sAMAccountType", ADS_ATTR_SFU_HOMEDIR_OID, - ADS_ATTR_SFU_SHELL_OID, + ADS_ATTR_SFU_SHELL_OID, + ADS_ATTR_SFU_GECOS_OID, NULL}; int i, count; ADS_STATUS rc; @@ -191,7 +192,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, i = 0; for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - char *name, *gecos; + char *name, *gecos = NULL; char *homedir = NULL; char *shell = NULL; uint32 group; @@ -204,10 +205,18 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, } name = ads_pull_username(ads, mem_ctx, msg); - gecos = ads_pull_string(ads, mem_ctx, msg, "name"); + if (use_nss_info("sfu")) { - homedir = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_homedir_attr); - shell = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_shell_attr); + homedir = ads_pull_string(ads, mem_ctx, msg, + ads->schema.sfu_homedir_attr); + shell = ads_pull_string(ads, mem_ctx, msg, + ads->schema.sfu_shell_attr); + gecos = ads_pull_string(ads, mem_ctx, msg, + ads->schema.sfu_gecos_attr); + } + + if (gecos == NULL) { + gecos = ads_pull_string(ads, mem_ctx, msg, "name"); } if (!ads_pull_sid(ads, msg, "objectSid", @@ -433,7 +442,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain, "name", "primaryGroupID", ADS_ATTR_SFU_HOMEDIR_OID, - ADS_ATTR_SFU_SHELL_OID, + ADS_ATTR_SFU_SHELL_OID, + ADS_ATTR_SFU_GECOS_OID, NULL}; ADS_STATUS rc; int count; @@ -471,11 +481,23 @@ static NTSTATUS query_user(struct winbindd_domain *domain, } info->acct_name = ads_pull_username(ads, mem_ctx, msg); - info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); if (use_nss_info("sfu")) { +<<<<<<< .working info->homedir = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_homedir_attr); info->shell = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_shell_attr); +======= + info->homedir = ads_pull_string(ads, mem_ctx, msg, + ads->schema.sfu_homedir_attr); + info->shell = ads_pull_string(ads, mem_ctx, msg, + ads->schema.sfu_shell_attr); + info->full_name = ads_pull_string(ads, mem_ctx, msg, + ads->schema.sfu_gecos_attr); +>>>>>>> .merge-right.r13657 + } + + if (info->full_name == NULL) { + info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); } if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) { diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c index 23c66acf26e..c5c3b49d15d 100644 --- a/source/rpc_client/cli_pipe.c +++ b/source/rpc_client/cli_pipe.c @@ -2393,13 +2393,14 @@ struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, /**************************************************************************** Open a netlogon pipe and get the schannel session key. + Now exposed to external callers. ****************************************************************************/ -static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, +struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, const char *domain, + uint32 *pneg_flags, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; @@ -2438,7 +2439,7 @@ static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, machine_account, /* machine account name */ machine_pwd, sec_chan_type, - &neg_flags); + pneg_flags); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds " @@ -2448,7 +2449,7 @@ static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, return NULL; } - if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) { + if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n", cli->desthost)); cli_rpc_pipe_close(netlogon_pipe); @@ -2520,9 +2521,9 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ const char *domain, const char *username, const char *password, + uint32 *pneg_flags, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; @@ -2564,7 +2565,7 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ machine_account, /* machine account name */ machine_pwd, sec_chan_type, - &neg_flags); + pneg_flags); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(3,("get_schannel_session_key_auth_ntlmssp: rpccli_netlogon_setup_creds " @@ -2574,7 +2575,7 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ return NULL; } - if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) { + if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { DEBUG(3, ("get_schannel_session_key_auth_ntlmssp: Server %s did not offer schannel\n", cli->desthost)); cli_rpc_pipe_close(netlogon_pipe); @@ -2599,10 +2600,12 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state const char *password, NTSTATUS *perr) { + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; - netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username, password, perr); + netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username, + password, &neg_flags, perr); if (!netlogon_pipe) { DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session " "key from server %s for domain %s.\n", @@ -2631,10 +2634,11 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, const char *domain, NTSTATUS *perr) { + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; - netlogon_pipe = get_schannel_session_key(cli, domain, perr); + netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr); if (!netlogon_pipe) { DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session " "key from server %s for domain %s.\n", diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c index db061cb1b8c..5d2ed6a10d1 100644 --- a/source/smbd/negprot.c +++ b/source/smbd/negprot.c @@ -178,6 +178,7 @@ static int negprot_spnego(char *p, uint8 *pkeylen) OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; + const char *OIDs_plain[] = {OID_NTLMSSP, NULL}; int len; global_spnego_negotiated = True; @@ -212,9 +213,13 @@ static int negprot_spnego(char *p, uint8 *pkeylen) */ if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) { - memcpy(p, guid, 16); - *pkeylen = 0; - return 16; +#if 0 + /* Code for PocketPC client */ + blob = data_blob(guid, 16); +#else + /* Code for standalone WXP client */ + blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE"); +#endif } else { fstring myname; char *host_princ_s = NULL; @@ -224,14 +229,20 @@ static int negprot_spnego(char *p, uint8 *pkeylen) blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s); SAFE_FREE(host_princ_s); } + memcpy(p, blob.data, blob.length); len = blob.length; if (len > 256) { DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len)); len = 255; } - *pkeylen = len; data_blob_free(&blob); + + if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) { + *pkeylen = 0; + } else { + *pkeylen = len; + } return len; } diff --git a/source/utils/net_rpc_join.c b/source/utils/net_rpc_join.c index 29a27d8f647..1f68da0d754 100644 --- a/source/utils/net_rpc_join.c +++ b/source/utils/net_rpc_join.c @@ -43,31 +43,57 @@ **/ static int net_rpc_join_ok(const char *domain) { + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_hnd = NULL; - int retval = 1; - NTSTATUS ret; + struct rpc_pipe_client *netlogon_pipe = NULL; + NTSTATUS ntret = NT_STATUS_UNSUCCESSFUL; /* Connect to remote machine */ if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) { - return 1; + return -1; } - pipe_hnd = cli_rpc_pipe_open_schannel(cli, PI_NETLOGON, - PIPE_AUTH_LEVEL_PRIVACY, - domain, &ret); + /* Setup the creds as though we're going to do schannel... */ + netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, &ntret); + + /* We return NT_STATUS_INVALID_NETWORK_RESPONSE if the server is refusing + to negotiate schannel, but the creds were set up ok. That'll have to do. */ + + if (!netlogon_pipe) { + if (NT_STATUS_EQUAL(ntret, NT_STATUS_INVALID_NETWORK_RESPONSE)) { + cli_shutdown(cli); + return 0; + } else { + DEBUG(0,("net_rpc_join_ok: failed to get schannel session " + "key from server %s for domain %s. Error was %s\n", + cli->desthost, domain, nt_errstr(ntret) )); + cli_shutdown(cli); + return -1; + } + } - if (!pipe_hnd) { - DEBUG(0,("Error connecting to NETLOGON pipe. Error was %s\n", nt_errstr(ret) )); - goto done; + /* Only do the rest of the schannel test if the client is allowed to do this. */ + if (!lp_client_schannel()) { + cli_shutdown(cli); + /* We're good... */ + return 0; } - retval = 0; /* Success! */ - -done: + pipe_hnd = cli_rpc_pipe_open_schannel_with_key(cli, PI_NETLOGON, + PIPE_AUTH_LEVEL_PRIVACY, + domain, netlogon_pipe->dc, &ntret); + + if (!pipe_hnd) { + DEBUG(0,("net_rpc_join_ok: failed to open schannel session " + "on netlogon pipe to server %s for domain %s. Error was %s\n", + cli->desthost, domain, nt_errstr(ntret) )); + cli_shutdown(cli); + return -1; + } cli_shutdown(cli); - return retval; + return 0; } /** |