From: Jeremy Allison Date: Sat, 3 Nov 2001 23:34:24 +0000 (+0000) Subject: Added NT_USER_TOKEN into server_info to fix extra groups problem. X-Git-Url: http://git.samba.org/samba.git/?p=kai%2Fsamba.git;a=commitdiff_plain;h=f8e2baf39eb864481dd48f61404136b325cd73c2 Added NT_USER_TOKEN into server_info to fix extra groups problem. Got "medieval on our ass" about const warnings (as many as I could :-). Jeremy. (This used to be commit ee5e7ca547eff016818ba5c43b8ea0c9fa69b808) --- diff --git a/source3/Makefile.in b/source3/Makefile.in index ea15da5ca3c..4bced02721c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -399,7 +399,7 @@ WINBINDD_OBJ1 = \ NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ = \ libsmb/domain_client_validate.o smbd/auth_util.o \ - rpc_client/cli_netlogon.o rpc_client/cli_login.o + rpc_client/cli_netlogon.o rpc_client/cli_login.o WINBINDD_OBJ = \ $(WINBINDD_OBJ1) $(NOPROTO_OBJ) $(PASSDB_OBJ) \ diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 9de81425789..9a99b2643e5 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -4,6 +4,7 @@ Authentication utility functions Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Andrew Bartlett 2001 + Copyright (C) Jeremy Allison 2000-2001 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,21 +30,23 @@ extern fstring remote_machine; extern pstring global_myname; /******************************************************************* -Get the next challenge value - no repeats. + Get the next challenge value - no repeats. ********************************************************************/ + void generate_next_challenge(char *challenge) { - unsigned char buf[8]; + unsigned char buf[8]; - generate_random_buffer(buf,8,False); + generate_random_buffer(buf,8,False); memcpy(saved_challenge, buf, 8); memcpy(challenge,buf,8); challenge_sent = True; } /******************************************************************* -set the last challenge sent, usually from a password server + Set the last challenge sent, usually from a password server. ********************************************************************/ + BOOL set_challenge(unsigned char *challenge) { memcpy(saved_challenge,challenge,8); @@ -52,16 +55,17 @@ BOOL set_challenge(unsigned char *challenge) } /******************************************************************* -get the last challenge sent + Get the last challenge sent. ********************************************************************/ + BOOL last_challenge(unsigned char *challenge) { - if (!challenge_sent) return(False); + if (!challenge_sent) + return(False); memcpy(challenge,saved_challenge,8); return(True); } - /**************************************************************************** Create a UNIX user on demand. ****************************************************************************/ @@ -72,7 +76,8 @@ static int smb_create_user(const char *unix_user, const char *homedir) int ret; pstrcpy(add_script, lp_adduser_script()); - if (! *add_script) return -1; + if (! *add_script) + return -1; all_string_sub(add_script, "%u", unix_user, sizeof(pstring)); if (homedir) all_string_sub(add_script, "%H", homedir, sizeof(pstring)); @@ -91,7 +96,8 @@ static int smb_delete_user(char *unix_user) int ret; pstrcpy(del_script, lp_deluser_script()); - if (! *del_script) return -1; + if (! *del_script) + return -1; all_string_sub(del_script, "%u", unix_user, sizeof(pstring)); ret = smbrun(del_script,NULL); DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret)); @@ -131,7 +137,7 @@ void smb_user_control(const auth_usersupplied_info *user_info, auth_serversuppli if (home_dir && (sys_stat(home_dir, &st) == -1) && (errno == ENOENT)) { - smb_create_user(user_info->internal_username.str, home_dir); + smb_create_user(user_info->internal_username.str, home_dir); } } } @@ -641,14 +647,14 @@ void free_user_info(auth_usersupplied_info **user_info) /*************************************************************************** Clear out a server_info struct that has been allocated ***************************************************************************/ + void free_server_info(auth_serversupplied_info **server_info) { if (*server_info != NULL) { pdb_free_sam(&(*server_info)->sam_account); /* call pam_end here, unless we know we are keeping it */ - SAFE_FREE((*server_info)->group_rids); - + delete_nt_token( &(*server_info)->ptok ); ZERO_STRUCT(**server_info); } SAFE_FREE(*server_info); @@ -657,6 +663,7 @@ void free_server_info(auth_serversupplied_info **server_info) /*************************************************************************** Make a server_info struct for a guest user ***************************************************************************/ + void make_server_info_guest(auth_serversupplied_info **server_info) { struct passwd *pass = sys_getpwnam(lp_guestaccount(-1)); @@ -666,3 +673,42 @@ void make_server_info_guest(auth_serversupplied_info **server_info) } } +/**************************************************************************** + Delete a SID token. +****************************************************************************/ + +void delete_nt_token(NT_USER_TOKEN **pptoken) +{ + if (*pptoken) { + NT_USER_TOKEN *ptoken = *pptoken; + SAFE_FREE( ptoken->user_sids ); + ZERO_STRUCTP(ptoken); + } + SAFE_FREE(*pptoken); +} + +/**************************************************************************** + Duplicate a SID token. +****************************************************************************/ + +NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken) +{ + NT_USER_TOKEN *token; + + if (!ptoken) + return NULL; + + if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) + return NULL; + + ZERO_STRUCTP(token); + + if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) { + SAFE_FREE(token); + return NULL; + } + + token->num_sids = ptoken->num_sids; + + return token; +} diff --git a/source3/include/auth.h b/source3/include/auth.h index 427cb8b4899..04c5aa55e52 100644 --- a/source3/include/auth.h +++ b/source3/include/auth.h @@ -77,10 +77,9 @@ typedef struct serversupplied_info int n_groups; gid_t *groups; - /* NT group information taken from the info3 structure */ + /* NT group information taken from the info3 structure */ - int n_rids; - uint32 *group_rids; + NT_USER_TOKEN *ptok; uchar session_key[16]; diff --git a/source3/include/smb.h b/source3/include/smb.h index 0e48b4c6c0a..33a33037a8c 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -303,6 +303,9 @@ typedef struct sid_info * token->user_sids[2-num_sids] = supplementary group SIDS. */ +#define PRIMARY_USER_SID_INDEX 0 +#define PRIMARY_GROUP_SID_INDEX 1 + #ifndef _NT_USER_TOKEN typedef struct _nt_user_token { size_t num_sids; diff --git a/source3/lib/xfile.c b/source3/lib/xfile.c index 6e21aeca58f..7fc519e451a 100644 --- a/source3/lib/xfile.c +++ b/source3/lib/xfile.c @@ -163,7 +163,7 @@ int x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f) continue; } - memcpy(f->buf + f->bufused, total+(char *)p, n); + memcpy(f->buf + f->bufused, total+(const char *)p, n); f->bufused += n; total += n; } @@ -173,7 +173,7 @@ int x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f) if (f->buftype == X_IOLBF && f->bufused) { int i; for (i=size-1; i>=0; i--) { - if (*(i+(char *)p) == '\n') { + if (*(i+(const char *)p) == '\n') { x_fflush(f); break; } diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index a8c0eebb94c..50cf6a71421 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -32,14 +32,14 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) { if (data->has_error) return False; if (data->length < data->ofs+len) { - uint8 *p; - p = Realloc(data->data, data->ofs+len); - if (!p) { + uint8 *newp; + newp = Realloc(data->data, data->ofs+len); + if (!newp) { SAFE_FREE(data->data); data->has_error = True; return False; } - data->data = p; + data->data = newp; data->length = data->ofs+len; } memcpy(data->data + data->ofs, p, len); @@ -112,20 +112,27 @@ BOOL asn1_pop_tag(ASN1_DATA *data) BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) { unsigned v, v2; - char *p = (char *)OID; + const char *p = (const char *)OID; + char *newp; - if (!asn1_push_tag(data, ASN1_OID)) return False; - v = strtol(p, &p, 10); - v2 = strtol(p, &p, 10); - if (!asn1_write_uint8(data, 40*v + v2)) return False; + if (!asn1_push_tag(data, ASN1_OID)) + return False; + v = strtol(p, &newp, 10); + p = newp; + v2 = strtol(p, &newp, 10); + p = newp; + if (!asn1_write_uint8(data, 40*v + v2)) + return False; while (*p) { - v = strtol(p, &p, 10); + v = strtol(p, &newp, 10); + p = newp; if (v >= (1<<28)) asn1_write_uint8(data, 0x80 | ((v>>28)&0xff)); if (v >= (1<<21)) asn1_write_uint8(data, 0x80 | ((v>>21)&0xff)); if (v >= (1<<14)) asn1_write_uint8(data, 0x80 | ((v>>14)&0xff)); if (v >= (1<<7)) asn1_write_uint8(data, 0x80 | ((v>>7)&0xff)); - if (!asn1_write_uint8(data, v&0x7f)) return False; + if (!asn1_write_uint8(data, v&0x7f)) + return False; } return asn1_pop_tag(data); } diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index e9981d7205c..d9f8e19910a 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -212,7 +212,7 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) Used in smbtorture. ****************************************************************************/ -int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, +int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredAccess, uint32 FileAttributes, uint32 ShareAccess, uint32 CreateDisposition, uint32 CreateOptions) { @@ -268,7 +268,7 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, open a file ****************************************************************************/ -int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) +int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess) { return cli_nt_create_full(cli, fname, DesiredAccess, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0); @@ -278,7 +278,7 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) open a file WARNING: if you open with O_WRONLY then getattrE won't work! ****************************************************************************/ -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) +int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode) { char *p; unsigned openfn=0; diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 20db1ee4d68..7a8fa668412 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -352,25 +352,41 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, } } - /* Store the user group information in the server_info returned to - the caller. */ + /* Store the user group information in the server_info returned to the caller. */ - if (NT_STATUS_IS_OK(status)) { - if (((*server_info)->group_rids = malloc(info3.num_groups2 * - sizeof(uint32))) == NULL) { - DEBUG(1, ("out of memory allocating rid group membership\n")); + if (NT_STATUS_IS_OK(status) && (info3.num_groups2 != 0)) { + DOM_SID domain_sid; + int i; + NT_USER_TOKEN *ptok; + auth_serversupplied_info *pserver_info = *server_info; + + if ((pserver_info->ptok = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) { + DEBUG(0, ("domain_client_validate: out of memory allocating rid group membership\n")); status = NT_STATUS_NO_MEMORY; free_server_info(server_info); - } else { - int i; - - (*server_info)->n_rids = info3.num_groups2; - - for (i = 0; i < (*server_info)->n_rids; i++) { - (*server_info)->group_rids[i] = info3.gids[i].g_rid; - DEBUG(5, ("** adding group rid 0x%x\n", - info3.gids[i].g_rid)); - } + goto done; + } + + ptok = pserver_info->ptok; + ptok->num_sids = (size_t)info3.num_groups2; + + if ((ptok->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptok->num_sids )) == NULL) { + DEBUG(0, ("domain_client_validate: Out of memory allocating group SIDS\n")); + status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + DEBUG(0, ("domain_client_validate: unable to fetch domain sid.\n")); + status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + for (i = 0; i < ptok->num_sids; i++) { + sid_copy(&ptok->user_sids[i], &domain_sid); + sid_append_rid(&ptok->user_sids[i], info3.gids[i].g_rid); } } @@ -390,6 +406,8 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, } #endif /* 0 */ + done: + /* Note - once the cli stream is shutdown the mem_ctx used to allocate the other_sids and gids structures has been deleted - so these pointers are no longer valid..... */ diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 64e23e0febc..4a2c5f1604b 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -49,41 +49,31 @@ BOOL pwd_is_nullpwd(const struct pwd_info *pwd) /**************************************************************************** compares two passwords. hmm, not as trivial as expected. hmm. ****************************************************************************/ -BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2) +BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2) { - if (pwd1->cleartext && pwd2->cleartext) - { + if (pwd1->cleartext && pwd2->cleartext) { if (strequal(pwd1->password, pwd2->password)) - { return True; - } } if (pwd1->null_pwd && pwd2->null_pwd) - { return True; - } if (!pwd1->null_pwd && !pwd2->null_pwd && - !pwd1->cleartext && !pwd2->cleartext) - { + !pwd1->cleartext && !pwd2->cleartext) { #ifdef DEBUG_PASSWORD DEBUG(100,("pwd compare: nt#\n")); dump_data(100, pwd1->smb_nt_pwd, 16); dump_data(100, pwd2->smb_nt_pwd, 16); #endif if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) - { return True; - } #ifdef DEBUG_PASSWORD DEBUG(100,("pwd compare: lm#\n")); dump_data(100, pwd1->smb_lm_pwd, 16); dump_data(100, pwd2->smb_lm_pwd, 16); #endif if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0) - { return True; - } } return False; } diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c index 620dc9e7d9b..34c340f258c 100644 --- a/source3/nsswitch/winbindd_misc.c +++ b/source3/nsswitch/winbindd_misc.c @@ -67,7 +67,6 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat uchar trust_passwd[16]; struct in_addr *ip_list = NULL; int count; - uint16 validation_level; fstring controller, trust_account; int num_retries = 0; @@ -101,9 +100,12 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat global_myname); #if 0 /* XXX */ + { + uint16 validation_level; status = cli_nt_setup_creds(controller, lp_workgroup(), global_myname, trust_account, trust_passwd, SEC_CHAN_WKSTA, &validation_level); + } #endif /* There is a race condition between fetching the trust account diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9251f879d2d..6eaab39bcc7 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -896,7 +896,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, Set the handle state. ****************************************************************************/ -static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state) +static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, const char *pipe_name, uint16 device_state) { BOOL state_set = False; char param[2]; @@ -940,7 +940,7 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1 check the rpc bind acknowledge response ****************************************************************************/ -static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer) +static BOOL valid_pipe_name(const char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer) { int pipe_idx = 0; @@ -970,7 +970,7 @@ static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *tra check the rpc bind acknowledge response ****************************************************************************/ -static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer) +static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const char *pipe_name, RPC_IFACE *transfer) { int i = 0; @@ -1104,7 +1104,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 Do an rpc bind. ****************************************************************************/ -BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name) +BOOL rpc_pipe_bind(struct cli_state *cli, const char *pipe_name, char *my_name) { RPC_IFACE abstract; RPC_IFACE transfer; @@ -1189,16 +1189,16 @@ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) Open a session. ****************************************************************************/ -BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) +BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name) { int fnum; SMB_ASSERT(cli->nt_pipe_fnum == 0); if (cli->capabilities & CAP_NT_SMBS) { - if ((fnum = cli_nt_create(cli, &(pipe_name[5]), DESIRED_ACCESS_PIPE)) == -1) { + if ((fnum = cli_nt_create(cli, &pipe_name[5], DESIRED_ACCESS_PIPE)) == -1) { DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n", - &(pipe_name[5]), cli->desthost, cli_errstr(cli))); + &pipe_name[5], cli->desthost, cli_errstr(cli))); return False; } diff --git a/source3/rpc_client/cli_use.c b/source3/rpc_client/cli_use.c index acdfe46fda5..2809f8c69fd 100644 --- a/source3/rpc_client/cli_use.c +++ b/source3/rpc_client/cli_use.c @@ -170,7 +170,7 @@ static struct cli_use *cli_find(const char *srv_name, { continue; } - if (!reuse && !pwd_compare((struct pwd_info *)&usr_creds->pwd, &c->cli->pwd)) + if (!reuse && !pwd_compare(&usr_creds->pwd, &c->cli->pwd)) { DEBUG(100, ("password doesn't match\n")); continue; diff --git a/source3/rpc_client/ncacn_np_use.c b/source3/rpc_client/ncacn_np_use.c index d903b40c144..137be635f7e 100644 --- a/source3/rpc_client/ncacn_np_use.c +++ b/source3/rpc_client/ncacn_np_use.c @@ -74,7 +74,7 @@ static BOOL ncacn_np_establish_connection(struct ncacn_np *cli, return False; } /* if (!cli_nt_session_open(cli->smb, pipe_name, &cli->fnum)) by JERRY */ - if (!cli_nt_session_open(cli->smb, (char *)pipe_name)) + if (!cli_nt_session_open(cli->smb, pipe_name)) { cli_net_use_del(srv_name, ntc, False, NULL); return False; @@ -328,19 +328,16 @@ static struct ncacn_np_use *ncacn_np_find(const char *srv_name, continue; } if (!reuse - && !pwd_compare((struct pwd_info *)&usr_creds->pwd, &c->cli->smb->pwd)) + && !pwd_compare(&usr_creds->pwd, &c->cli->smb->pwd)) { DEBUG(100, ("password doesn't match\n")); continue; } if (usr_creds->domain[0] == 0) - { return c; - } + if (strequal(usr_creds->domain, c->cli->smb->domain)) - { return c; - } } return NULL; diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 76f4a1ed1e3..dfe03c2eb34 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -447,7 +447,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name /* Create an NT_USER_TOKEN struct for this user. */ p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, p->pipe_user.ngroups, p->pipe_user.groups, - guest_user); + guest_user, NULL); p->ntlmssp_auth_validated = True; diff --git a/source3/smbd/auth_util.c b/source3/smbd/auth_util.c index 9de81425789..9a99b2643e5 100644 --- a/source3/smbd/auth_util.c +++ b/source3/smbd/auth_util.c @@ -4,6 +4,7 @@ Authentication utility functions Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Andrew Bartlett 2001 + Copyright (C) Jeremy Allison 2000-2001 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,21 +30,23 @@ extern fstring remote_machine; extern pstring global_myname; /******************************************************************* -Get the next challenge value - no repeats. + Get the next challenge value - no repeats. ********************************************************************/ + void generate_next_challenge(char *challenge) { - unsigned char buf[8]; + unsigned char buf[8]; - generate_random_buffer(buf,8,False); + generate_random_buffer(buf,8,False); memcpy(saved_challenge, buf, 8); memcpy(challenge,buf,8); challenge_sent = True; } /******************************************************************* -set the last challenge sent, usually from a password server + Set the last challenge sent, usually from a password server. ********************************************************************/ + BOOL set_challenge(unsigned char *challenge) { memcpy(saved_challenge,challenge,8); @@ -52,16 +55,17 @@ BOOL set_challenge(unsigned char *challenge) } /******************************************************************* -get the last challenge sent + Get the last challenge sent. ********************************************************************/ + BOOL last_challenge(unsigned char *challenge) { - if (!challenge_sent) return(False); + if (!challenge_sent) + return(False); memcpy(challenge,saved_challenge,8); return(True); } - /**************************************************************************** Create a UNIX user on demand. ****************************************************************************/ @@ -72,7 +76,8 @@ static int smb_create_user(const char *unix_user, const char *homedir) int ret; pstrcpy(add_script, lp_adduser_script()); - if (! *add_script) return -1; + if (! *add_script) + return -1; all_string_sub(add_script, "%u", unix_user, sizeof(pstring)); if (homedir) all_string_sub(add_script, "%H", homedir, sizeof(pstring)); @@ -91,7 +96,8 @@ static int smb_delete_user(char *unix_user) int ret; pstrcpy(del_script, lp_deluser_script()); - if (! *del_script) return -1; + if (! *del_script) + return -1; all_string_sub(del_script, "%u", unix_user, sizeof(pstring)); ret = smbrun(del_script,NULL); DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret)); @@ -131,7 +137,7 @@ void smb_user_control(const auth_usersupplied_info *user_info, auth_serversuppli if (home_dir && (sys_stat(home_dir, &st) == -1) && (errno == ENOENT)) { - smb_create_user(user_info->internal_username.str, home_dir); + smb_create_user(user_info->internal_username.str, home_dir); } } } @@ -641,14 +647,14 @@ void free_user_info(auth_usersupplied_info **user_info) /*************************************************************************** Clear out a server_info struct that has been allocated ***************************************************************************/ + void free_server_info(auth_serversupplied_info **server_info) { if (*server_info != NULL) { pdb_free_sam(&(*server_info)->sam_account); /* call pam_end here, unless we know we are keeping it */ - SAFE_FREE((*server_info)->group_rids); - + delete_nt_token( &(*server_info)->ptok ); ZERO_STRUCT(**server_info); } SAFE_FREE(*server_info); @@ -657,6 +663,7 @@ void free_server_info(auth_serversupplied_info **server_info) /*************************************************************************** Make a server_info struct for a guest user ***************************************************************************/ + void make_server_info_guest(auth_serversupplied_info **server_info) { struct passwd *pass = sys_getpwnam(lp_guestaccount(-1)); @@ -666,3 +673,42 @@ void make_server_info_guest(auth_serversupplied_info **server_info) } } +/**************************************************************************** + Delete a SID token. +****************************************************************************/ + +void delete_nt_token(NT_USER_TOKEN **pptoken) +{ + if (*pptoken) { + NT_USER_TOKEN *ptoken = *pptoken; + SAFE_FREE( ptoken->user_sids ); + ZERO_STRUCTP(ptoken); + } + SAFE_FREE(*pptoken); +} + +/**************************************************************************** + Duplicate a SID token. +****************************************************************************/ + +NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken) +{ + NT_USER_TOKEN *token; + + if (!ptoken) + return NULL; + + if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) + return NULL; + + ZERO_STRUCTP(token); + + if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) { + SAFE_FREE(token); + return NULL; + } + + token->num_sids = ptoken->num_sids; + + return token; +} diff --git a/source3/smbd/dfree.c b/source3/smbd/dfree.c index 13a3e86c6e1..51f06149419 100644 --- a/source3/smbd/dfree.c +++ b/source3/smbd/dfree.c @@ -121,7 +121,7 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query, } else sys_fsusage(path, dfree, dsize); - if (disk_quotas((char *)path, &bsize_q, &dfree_q, &dsize_q)) { + if (disk_quotas(path, &bsize_q, &dfree_q, &dsize_q)) { (*bsize) = bsize_q; (*dfree) = MIN(*dfree,dfree_q); (*dsize) = MIN(*dsize,dsize_q); diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 01eabfda5eb..429d72b4e51 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -117,7 +117,7 @@ char *validated_domain(uint16 vuid) Create the SID list for this user. ****************************************************************************/ -NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest) +NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest, NT_USER_TOKEN *sup_tok) { extern DOM_SID global_sid_World; extern DOM_SID global_sid_Network; @@ -137,6 +137,9 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, /* We always have uid/gid plus World and Network and Authenticated Users or Guest SIDs. */ num_sids = 5 + ngroups; + if (sup_tok && sup_tok->num_sids) + num_sids += sup_tok->num_sids; + if ((token->user_sids = (DOM_SID *)malloc( num_sids*sizeof(DOM_SID))) == NULL) { SAFE_FREE(token); return NULL; @@ -149,13 +152,15 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, * se_access_check depends on this. */ - uid_to_sid( &psids[psid_ndx++], uid); + uid_to_sid( &psids[PRIMARY_USER_SID_INDEX], uid); + psid_ndx++; /* * Primary group SID is second in token. Convention. */ - gid_to_sid( &psids[psid_ndx++], gid); + gid_to_sid( &psids[PRIMARY_GROUP_SID_INDEX], gid); + psid_ndx++; /* Now add the group SIDs. */ @@ -165,6 +170,10 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, } } + /* Now add the additional SIDs from the supplimentary token. */ + for (i = 0; i < sup_tok->num_sids; i++) + sid_copy( &psids[psid_ndx++], &sup_tok->user_sids[i] ); + /* * Finally add the "standard" SIDs. * The only difference between guest and "anonymous" (which we @@ -218,8 +227,8 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL gu ZERO_STRUCTP(vuser); - puid = pdb_get_uid(server_info->sam_account); - pgid = pdb_get_gid(server_info->sam_account); + puid = pdb_get_uid(server_info->sam_account); + pgid = pdb_get_gid(server_info->sam_account); if (!puid || !pgid) { DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT\n")); @@ -261,8 +270,11 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL gu initialise_groups(vuser->user.unix_name, vuser->uid, vuser->gid); get_current_groups( &vuser->n_groups, &vuser->groups); + if (server_info->ptok) + add_supplementary_nt_login_groups(&vuser->n_groups, &vuser->groups, &server_info->ptok); + /* Create an NT_USER_TOKEN struct for this user. */ - vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, guest); + vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, guest, server_info->ptok); DEBUG(3,("uid %d registered to name %s\n",(int)vuser->uid,vuser->user.unix_name)); diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c index 76d1124aea9..96670a985d2 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -114,7 +114,7 @@ static int get_smb_linux_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA try to get the disk space from disk quotas (LINUX version) ****************************************************************************/ -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r; SMB_STRUCT_STAT S; @@ -199,7 +199,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U try to get the disk space from disk quotas (CRAY VERSION) ****************************************************************************/ -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { struct mntent *mnt; FILE *fd; @@ -479,7 +479,7 @@ try to get the disk space from disk quotas (SunOS & Solaris2 version) Quota code by Peter Urbanec (amiga@cse.unsw.edu.au). ****************************************************************************/ -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { uid_t euser_id; int ret; @@ -639,7 +639,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U try to get the disk space from disk quotas - OSF1 version ****************************************************************************/ -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r, save_errno; struct dqblk D; @@ -705,7 +705,7 @@ try to get the disk space from disk quotas (IRIX 6.2 version) #include #include -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { uid_t euser_id; int r; @@ -843,7 +843,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U try to get the disk space from disk quotas - default version ****************************************************************************/ -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r; struct dqblk D; diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c index fd69521d4e1..b774947d607 100644 --- a/source3/smbd/sec_ctx.c +++ b/source3/smbd/sec_ctx.c @@ -168,46 +168,6 @@ int get_current_groups(int *p_ngroups, gid_t **p_groups) return ngroups; } -/**************************************************************************** - Delete a SID token. -****************************************************************************/ - -void delete_nt_token(NT_USER_TOKEN **pptoken) -{ - if (*pptoken) { - NT_USER_TOKEN *ptoken = *pptoken; - SAFE_FREE( ptoken->user_sids ); - ZERO_STRUCTP(ptoken); - } - SAFE_FREE(*pptoken); -} - -/**************************************************************************** - Duplicate a SID token. -****************************************************************************/ - -NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken) -{ - NT_USER_TOKEN *token; - - if (!ptoken) - return NULL; - - if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) - return NULL; - - ZERO_STRUCTP(token); - - if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) { - SAFE_FREE(token); - return NULL; - } - - token->num_sids = ptoken->num_sids; - - return token; -} - /**************************************************************************** Initialize the groups a user belongs to. ****************************************************************************/ diff --git a/source3/smbd/service.c b/source3/smbd/service.c index f6296201ae4..49fbee2607d 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -533,7 +533,7 @@ connection_struct *make_connection(char *service, DATA_BLOB password, conn->nt_user_token = create_nt_token(conn->uid, conn->gid, conn->ngroups, conn->groups, - guest); + guest, NULL); /* * New code to check if there's a share security descripter diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index ae287cca76b..b33c9ede17f 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -181,7 +181,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (vuser && vuser->guest) is_guest = True; - token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest); + token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest, NULL); must_free_token = True; } @@ -367,6 +367,75 @@ BOOL unbecome_user(void) return True; } +/***************************************************************** + Convert the suplimentary SIDs returned in a netlogon into UNIX + group gid_t's. Add to the total group array. +*****************************************************************/ + +void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER_TOKEN **pptok) +{ + int total_groups; + int current_n_groups = *n_groups; + gid_t *final_groups = NULL; + size_t i; + NT_USER_TOKEN *ptok = *pptok; + NT_USER_TOKEN *new_tok = NULL; + + if (!ptok || (ptok->num_sids == 0)) + return; + + new_tok = dup_nt_token(ptok); + if (!new_tok) { + DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new token\n")); + return; + } + /* Leave the allocated space but empty the number of SIDs. */ + new_tok->num_sids = 0; + + total_groups = current_n_groups + ptok->num_sids; + + final_groups = (gid_t *)malloc(total_groups * sizeof(gid_t)); + if (!final_groups) { + DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new groups.\n")); + delete_nt_token(&new_tok); + return; + } + + memcpy(final_groups, *pp_groups, current_n_groups * sizeof(gid_t)); + for (i = 0; i < ptok->num_sids; i++) { + enum SID_NAME_USE sid_type; + gid_t new_grp; + + if (sid_to_gid(&ptok->user_sids[i], &new_grp, &sid_type)) { + /* + * Don't add the gid_t if it is already in the current group + * list. Some UNIXen don't like the same group more than once. + */ + int j; + + for (j = 0; j < current_n_groups; j++) + if (final_groups[j] == new_grp) + break; + + if ( j == current_n_groups) { + /* Group not already present. */ + final_groups[current_n_groups++] = new_grp; + } + } else { + /* SID didn't map. Copy to the new token to be saved. */ + sid_copy(&new_tok->user_sids[new_tok->num_sids++], &ptok->user_sids[i]); + } + } + + SAFE_FREE(*pp_groups); + *pp_groups = final_groups; + *n_groups = current_n_groups; + + /* Replace the old token with the truncated one. */ + delete_nt_token(&ptok); + *pptok = new_tok; +} + /***************************************************************** *THE CANONICAL* convert name to SID function. Tries winbind first - then uses local lookup. diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 3c417eebc33..443aa674eb4 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -79,10 +79,10 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst if (verbosity) { printf ("username: %s\n", sam_pwent->username); - printf ("user ID/Group: %d/%d\n", sam_pwent->uid, - sam_pwent->gid); - printf ("user RID/GRID: %d/%d\n", sam_pwent->user_rid, - sam_pwent->group_rid); + printf ("user ID/Group: %u/%u\n", (unsigned int)sam_pwent->uid, + (unsigned int)sam_pwent->gid); + printf ("user RID/GRID: %u/%u\n", (unsigned int)sam_pwent->user_rid, + (unsigned int)sam_pwent->group_rid); printf ("Full Name: %s\n", sam_pwent->full_name); printf ("Home Directory: %s\n", sam_pwent->home_dir); printf ("HomeDir Drive: %s\n", sam_pwent->dir_drive);