From 8ac22d6944c366f806253bf905567884feb709e4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 27 Nov 2003 04:40:58 +0000 Subject: use samr_dispinfo(level == 1) for enumerating domain users so we can include the full name in gecos field; bug 587 (This used to be commit 5482ff71729b623c4561e42b82467bf2d5d64082) --- source3/nsswitch/winbindd_rpc.c | 51 +++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index ba14a51d24..b13d419110 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -41,6 +41,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, BOOL got_dom_pol = False; uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; unsigned int i, start_idx, retry; + uint32 loop_count; DEBUG(3,("rpc: query_user_list\n")); @@ -67,25 +68,36 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, got_dom_pol = True; i = start_idx = 0; + loop_count = 0; + do { TALLOC_CTX *ctx2; - char **dom_users; - uint32 num_dom_users, *dom_rids, j, size = 0xffff; - uint16 acb_mask = ACB_NORMAL; - + uint32 num_dom_users, j; + uint32 max_entries, max_size; + SAM_DISPINFO_CTR ctr; + SAM_DISPINFO_1 info1; + + ZERO_STRUCT( ctr ); + ZERO_STRUCT( info1 ); + ctr.sam.info1 = &info1; + if (!(ctx2 = talloc_init("winbindd enum_users"))) { result = NT_STATUS_NO_MEMORY; goto done; } - result = cli_samr_enum_dom_users( - hnd->cli, ctx2, &dom_pol, &start_idx, acb_mask, - size, &dom_users, &dom_rids, &num_dom_users); + /* this next bit is copied from net_user_list_internal() */ + + get_query_dispinfo_params( loop_count, &max_entries, &max_size ); + + result = cli_samr_query_dispinfo(hnd->cli, mem_ctx, &dom_pol, + &start_idx, 1, &num_dom_users, max_entries, max_size, &ctr); + + loop_count++; *num_entries += num_dom_users; - *info = talloc_realloc( - mem_ctx, *info, + *info = talloc_realloc( mem_ctx, *info, (*num_entries) * sizeof(WINBIND_USERINFO)); if (!(*info)) { @@ -95,10 +107,16 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, } for (j = 0; j < num_dom_users; i++, j++) { - (*info)[i].acct_name = - talloc_strdup(mem_ctx, dom_users[j]); - (*info)[i].full_name = talloc_strdup(mem_ctx, ""); - (*info)[i].user_sid = rid_to_talloced_sid(domain, mem_ctx, dom_rids[j]); + fstring username, fullname; + uint32 rid = ctr.sam.info1->sam[j].rid_user; + + unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username)-1); + unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1); + + (*info)[i].acct_name = talloc_strdup(mem_ctx, username ); + (*info)[i].full_name = talloc_strdup(mem_ctx, fullname ); + (*info)[i].user_sid = rid_to_talloced_sid(domain, mem_ctx, rid ); + /* For the moment we set the primary group for every user to be the Domain Users group. There are serious problems with determining @@ -106,10 +124,9 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, This should really be made into a 'winbind force group' smb.conf parameter or something like that. */ - (*info)[i].group_sid - = rid_to_talloced_sid(domain, - mem_ctx, - DOMAIN_GROUP_RID_USERS); + + (*info)[i].group_sid = rid_to_talloced_sid(domain, + mem_ctx, DOMAIN_GROUP_RID_USERS); } talloc_destroy(ctx2); -- cgit From 2385a310d33dad825d4489e7cb7a8b1e79ec0073 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 27 Nov 2003 17:32:13 +0000 Subject: Only ask for 512 names at a time. Volker (This used to be commit 73cdf724e90d76e97895ae5b1326825bb59bf90e) --- source3/utils/net_rpc.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index af575d9585..2453355ee3 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1125,16 +1125,27 @@ rpc_group_members_internals(const DOM_SID *domain_sid, struct cli_state *cli, if (!NT_STATUS_IS_OK(result)) goto done; - result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol, 1000, - num_members, group_rids, - &num_names, &names, &name_types); + do { + int this_time = 512; - if (!NT_STATUS_IS_OK(result)) - goto done; + if (num_members < this_time) + this_time = num_members; - for (i = 0; i < num_members; i++) { - printf("%s\n", names[i]); - } + result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol, 1000, + this_time, group_rids, + &num_names, &names, &name_types); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + for (i = 0; i < this_time; i++) { + printf("%s\n", names[i]); + } + + num_members -= this_time; + group_rids += 512; + + } while (num_members > 0); done: return result; -- cgit From 94ca6711cfac99b1c11a665b608b969c6ac9ebbf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Nov 2003 18:34:40 +0000 Subject: Fix for pdbedit error code returns (sorry, forgot who sent in the patch). Jeremy. (This used to be commit 37c96290592607b5e731d0b8933be825d93b70f0) --- source3/utils/pdbedit.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index c69b149469..d72634d78b 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -489,7 +489,11 @@ static int delete_user_entry (struct pdb_context *in, const char *username) return -1; } - return NT_STATUS_IS_OK(in->pdb_delete_sam_account (in, samaccount)); + if (!NT_STATUS_IS_OK(in->pdb_delete_sam_account (in, samaccount))) { + fprintf (stderr, "Unable to delete user %s\n", username); + return -1; + } + return 0; } /********************************************************* @@ -515,7 +519,12 @@ static int delete_machine_entry (struct pdb_context *in, const char *machinename return -1; } - return NT_STATUS_IS_OK(in->pdb_delete_sam_account (in, samaccount)); + if (!NT_STATUS_IS_OK(in->pdb_delete_sam_account (in, samaccount))) { + fprintf (stderr, "Unable to delete machine %s\n", name); + return -1; + } + + return 0; } /********************************************************* -- cgit From 958f1e54f71191d94498da45fc505d96b1528c78 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Nov 2003 15:10:30 +0000 Subject: Implement 'net rpc group list [global|local|builtin]*' for a select listing of the respective user databases. Volker (This used to be commit 53b592f4a64742767f37f9c7f8ee0fdf42e686c6) --- source3/utils/net_help.c | 2 ++ source3/utils/net_rpc.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index 059da4740b..514cf1af1b 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -88,6 +88,8 @@ int net_help_group(int argc, const char **argv) { d_printf("net [] group [misc. options] [targets]"\ "\n\tList user groups\n\n"); + d_printf("net rpc group LIST [global|local|builtin]* [misc. options]"\ + "\n\tList specific user groups\n\n"); d_printf("net [] group DELETE "\ "[misc. options] [targets]"\ "\n\tDelete specified group\n"); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 2453355ee3..75b3726b44 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -916,6 +916,26 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0; struct acct_info *groups; DOM_SID global_sid_Builtin; + BOOL global = False; + BOOL local = False; + BOOL builtin = False; + + if (argc == 0) { + global = True; + local = True; + builtin = True; + } + + for (i=0; i Date: Sun, 30 Nov 2003 19:40:53 +0000 Subject: Fix signing bug with secondary client trans requests. Turns out the last packet is the one that matters for checking the signing replies. Need to check the server code does this correctly too.... Bug #832 reported by Volker. Jeremy. (This used to be commit 315f25fc1710e20051414bbf084cb5648129c3bb) --- source3/libsmb/clitrans.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 92c1cc99ee..3eb7fcc216 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -134,6 +134,16 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, * the primary. Important in signing. JRA. */ cli->mid = mid; + /* + * Turns out that we need to increment the + * sequence number for each packet until the + * last one in the signing sequence. That's + * the one that matters to check signing replies. JRA. + */ + + cli_signing_trans_stop(cli); + cli_signing_trans_start(cli); + show_msg(cli->outbuf); if (!cli_send_smb(cli)) { cli_signing_trans_stop(cli); @@ -427,6 +437,16 @@ BOOL cli_send_nt_trans(struct cli_state *cli, * the primary. Important in signing. JRA. */ cli->mid = mid; + /* + * Turns out that we need to increment the + * sequence number for each packet until the + * last one in the signing sequence. That's + * the one that matters to check signing replies. JRA. + */ + + cli_signing_trans_stop(cli); + cli_signing_trans_start(cli); + show_msg(cli->outbuf); if (!cli_send_smb(cli)) { -- cgit From 003f2cb9f9bcf5c7ae7265fe13757ed385d5bbaa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 01:04:02 +0000 Subject: Better fix for client signing bug. Ensure we don't malloc/free trans signing state info each packet. Jeremy. (This used to be commit c662e2dbc4d953b3718f69fef4517a3e7539151e) --- source3/libsmb/clitrans.c | 56 ++++++++++++++++++++------------------------ source3/libsmb/smb_signing.c | 20 +++++++++++----- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3eb7fcc216..1602dcc683 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -50,6 +50,12 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, SCVAL(cli->outbuf,smb_com,trans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); + + /* + * Save the mid we're using. We need this for finding + * signing replies. + */ + mid = cli->mid; if (pipe_name) { @@ -87,16 +93,13 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, show_msg(cli->outbuf); - cli_signing_trans_start(cli); if (!cli_send_smb(cli)) { - cli_signing_trans_stop(cli); return False; } if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - cli_signing_trans_stop(cli); return(False); } @@ -130,23 +133,14 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); - /* Ensure this packet has the same MID as - * the primary. Important in signing. JRA. */ - cli->mid = mid; - /* - * Turns out that we need to increment the - * sequence number for each packet until the - * last one in the signing sequence. That's - * the one that matters to check signing replies. JRA. + * Save the mid we're using. We need this for finding + * signing replies. */ - - cli_signing_trans_stop(cli); - cli_signing_trans_start(cli); + mid = cli->mid; show_msg(cli->outbuf); if (!cli_send_smb(cli)) { - cli_signing_trans_stop(cli); return False; } @@ -155,6 +149,10 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, } } + /* Note we're in a trans state. Save the sequence + * numbers for replies. */ + + cli_signing_trans_start(cli, mid); return(True); } @@ -362,6 +360,12 @@ BOOL cli_send_nt_trans(struct cli_state *cli, SCVAL(cli->outbuf,smb_com,SMBnttrans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); + + /* + * Save the mid we're using. We need this for finding + * signing replies. + */ + mid = cli->mid; outparam = smb_buf(cli->outbuf)+3; @@ -391,16 +395,13 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_signing_trans_start(cli); if (!cli_send_smb(cli)) { - cli_signing_trans_stop(cli); return False; } if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - cli_signing_trans_stop(cli); return(False); } @@ -433,24 +434,15 @@ BOOL cli_send_nt_trans(struct cli_state *cli, memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); - /* Ensure this packet has the same MID as - * the primary. Important in signing. JRA. */ - cli->mid = mid; - /* - * Turns out that we need to increment the - * sequence number for each packet until the - * last one in the signing sequence. That's - * the one that matters to check signing replies. JRA. + * Save the mid we're using. We need this for finding + * signing replies. */ - - cli_signing_trans_stop(cli); - cli_signing_trans_start(cli); + mid = cli->mid; show_msg(cli->outbuf); if (!cli_send_smb(cli)) { - cli_signing_trans_stop(cli); return False; } @@ -459,6 +451,10 @@ BOOL cli_send_nt_trans(struct cli_state *cli, } } + /* Note we're in a trans state. Save the sequence + * numbers for replies. */ + + cli_signing_trans_start(cli, mid); return(True); } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 755a1548eb..cb35fda220 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -457,9 +457,12 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_ /*********************************************************** Tell client code we are in a multiple trans reply state. + We call this after the last outgoing trans2 packet (which + has incremented the sequence numbers), so we must save the + current mid and sequence number -2. ************************************************************/ -void cli_signing_trans_start(struct cli_state *cli) +void cli_signing_trans_start(struct cli_state *cli, uint16 mid) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; @@ -469,9 +472,9 @@ void cli_signing_trans_start(struct cli_state *cli) data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); ZERO_STRUCTP(data->trans_info); - data->trans_info->send_seq_num = data->send_seq_num; - data->trans_info->mid = SVAL(cli->outbuf,smb_mid); - data->trans_info->reply_seq_num = data->send_seq_num+1; + data->trans_info->send_seq_num = data->send_seq_num-2; + data->trans_info->mid = mid; + data->trans_info->reply_seq_num = data->send_seq_num-1; DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ data->send_seq_num = %u\n", @@ -492,10 +495,15 @@ void cli_signing_trans_stop(struct cli_state *cli) if (!cli->sign_info.doing_signing || !data) return; + DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)data->trans_info->mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); + SAFE_FREE(data->trans_info); data->trans_info = NULL; - - data->send_seq_num += 2; } /*********************************************************** -- cgit From c05411beae9969b1dca9de1412a7a5f432915d51 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 02:25:53 +0000 Subject: Don't automatically set nt status code flag unless client tells us it can cope. Jeremy. (This used to be commit dd1ac8d5eba060dcd7fdde7449d07bee1dc12b27) --- source3/smbd/process.c | 15 ++++++++++----- source3/smbd/sesssetup.c | 28 +++++++++++++++++++--------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 8a90a15d29..d93826bc7e 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -924,11 +924,17 @@ const char *smb_fn_name(int type) return(smb_messages[type].name); } - /**************************************************************************** - Helper function for contruct_reply. + Helper functions for contruct_reply. ****************************************************************************/ +static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_EXTENDED_SECURITY; + +void add_to_common_flags2(uint32 v) +{ + common_flags2 |= v; +} + void construct_reply_common(char *inbuf,char *outbuf) { memset(outbuf,'\0',smb_size); @@ -941,9 +947,8 @@ void construct_reply_common(char *inbuf,char *outbuf) SCVAL(outbuf,smb_reh,0); SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); SSVAL(outbuf,smb_flg2, - (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) | - FLAGS2_LONG_PATH_COMPONENTS | - FLAGS2_32_BIT_ERROR_CODES | FLAGS2_EXTENDED_SECURITY); + (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) | + common_flags2); SSVAL(outbuf,smb_err,SMB_SUCCESS); SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid)); diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 64c25db2ab..fb0744bb73 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -472,6 +472,11 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, if (global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv10); + + if (global_client_caps & CAP_STATUS32) { + add_to_common_flags2(FLAGS2_32_BIT_ERROR_CODES); + } + } p = (uint8 *)smb_buf(inbuf); @@ -615,17 +620,22 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, enum remote_arch_types ra_type = get_remote_arch(); char *p = smb_buf(inbuf); - if(global_client_caps == 0) + if(global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv11); - /* client_caps is used as final determination if client is NT or Win95. - This is needed to return the correct error codes in some - circumstances. - */ + if (global_client_caps & CAP_STATUS32) { + add_to_common_flags2(FLAGS2_32_BIT_ERROR_CODES); + } + + /* client_caps is used as final determination if client is NT or Win95. + This is needed to return the correct error codes in some + circumstances. + */ - if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) { - if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) { - set_remote_arch( RA_WIN95); + if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) { + if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) { + set_remote_arch( RA_WIN95); + } } } @@ -686,7 +696,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, ra_lanman_string( native_lanman ); } - + if (SVAL(inbuf,smb_vwv4) == 0) { setup_new_vc_session(); } -- cgit From f9a2ba6e911d6c90ffd030a5ed928f41c919f78a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 03:24:53 +0000 Subject: Ensure we use the same mid for the secondary trans requests, W2K3 does this. Jeremy. (This used to be commit e5bb3fdf4c8b2bb5b098bfbc0b4b80d947aeac6c) --- source3/libsmb/clitrans.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 1602dcc683..ae44ca1a77 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -143,6 +143,9 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, if (!cli_send_smb(cli)) { return False; } + + /* Ensure we use the same mid for the secondaries. */ + cli->mid = mid; tot_data += this_ldata; tot_param += this_lparam; @@ -446,6 +449,9 @@ BOOL cli_send_nt_trans(struct cli_state *cli, return False; } + /* Ensure we use the same mid for the secondaries. */ + cli->mid = mid; + tot_data += this_ldata; tot_param += this_lparam; } -- cgit From 95b77efc1bbe8c8f633676480fced19b9c129c3b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 06:19:14 +0000 Subject: Subtract NT_STATUS from common flag, don't add it... Jeremy. (This used to be commit 0ed153af55279ba1e621c688b5e78f842e72ea1e) --- source3/smbd/process.c | 6 +++--- source3/smbd/sesssetup.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source3/smbd/process.c b/source3/smbd/process.c index d93826bc7e..5206dc70f8 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -928,11 +928,11 @@ const char *smb_fn_name(int type) Helper functions for contruct_reply. ****************************************************************************/ -static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_EXTENDED_SECURITY; +static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_EXTENDED_SECURITY|FLAGS2_32_BIT_ERROR_CODES; -void add_to_common_flags2(uint32 v) +void remove_from_common_flags2(uint32 v) { - common_flags2 |= v; + common_flags2 &= ~v; } void construct_reply_common(char *inbuf,char *outbuf) diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index fb0744bb73..ec01a330ee 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -473,8 +473,8 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, if (global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv10); - if (global_client_caps & CAP_STATUS32) { - add_to_common_flags2(FLAGS2_32_BIT_ERROR_CODES); + if (!(global_client_caps & CAP_STATUS32)) { + remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); } } @@ -623,8 +623,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if(global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv11); - if (global_client_caps & CAP_STATUS32) { - add_to_common_flags2(FLAGS2_32_BIT_ERROR_CODES); + if (!(global_client_caps & CAP_STATUS32)) { + remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); } /* client_caps is used as final determination if client is NT or Win95. -- cgit From d75819ebcf072b7c8d428db413ec492db3f34075 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 06:53:21 +0000 Subject: Ensure the server can cope with multiple secondary trans requests when signing is turned on. Jeremy. (This used to be commit b97596df7834a80b648022e22983cab5dfb0f7dd) --- source3/smbd/ipc.c | 8 ++++++++ source3/smbd/nttrans.c | 8 ++++++++ source3/smbd/trans2.c | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 86d982b022..dd92cc4e4d 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -445,6 +445,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); show_msg(outbuf); + srv_signing_trans_stop(); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("reply_trans: send_smb failed."); } @@ -456,6 +457,13 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT); + /* + * The sequence number for the trans reply is always + * based on the last secondary received. + */ + + srv_signing_trans_start(SVAL(inbuf,smb_mid)); + if ((ret && (CVAL(inbuf, smb_com) != SMBtranss)) || !ret) { if(ret) { DEBUG(0,("reply_trans: Invalid secondary trans packet\n")); diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 8158c67a5e..25721d99a8 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -2489,6 +2489,7 @@ due to being in oplock break state.\n", (unsigned int)function_code )); /* We need to send an interim response then receive the rest of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); + srv_signing_trans_stop(); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("reply_nttrans: send_smb failed."); @@ -2499,6 +2500,13 @@ due to being in oplock break state.\n", (unsigned int)function_code )); ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT); + /* + * The sequence number for the trans reply is always + * based on the last secondary received. + */ + + srv_signing_trans_start(SVAL(inbuf,smb_mid)); + if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) { outsize = set_message(outbuf,0,0,True); if(ret) { diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 56d1aae3a2..525b015379 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3523,6 +3523,7 @@ int reply_trans2(connection_struct *conn, /* We need to send an interim response then receive the rest of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); + srv_signing_trans_stop(); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("reply_trans2: send_smb failed."); @@ -3536,6 +3537,13 @@ int reply_trans2(connection_struct *conn, ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT); + /* + * The sequence number for the trans reply is always + * based on the last secondary received. + */ + + srv_signing_trans_start(SVAL(inbuf,smb_mid)); + if ((ret && (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) { outsize = set_message(outbuf,0,0,True); -- cgit From 40a50473c4987b804d9401c0ae97110eedcca4f9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 06:59:56 +0000 Subject: Fix spurious error msg. when seq=0. Jeremy. (This used to be commit fd71acd1ffb3d3c2f2f82395c86512124769d592) --- source3/libsmb/smb_signing.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index cb35fda220..6b2abb9ccc 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -764,6 +764,8 @@ isn't sending correct signatures. Turning off.\n")); return True; } else { /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + if (saved_seq) + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u\n", (unsigned int)saved_seq)); return False; } } else { -- cgit From 04cc05b6b0354bf3250a501790319204feda9760 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 1 Dec 2003 14:02:24 +0000 Subject: I needed a decently parseable format of smbstatus. Looking at smbstatus code tells me that this should not be expanded, so I implemented net status [sessions|shares] [parseable] Volker (This used to be commit ed38341c8a6454a8ec0f8240d83239f6869536b8) --- source3/Makefile.in | 3 +- source3/utils/net.c | 1 + source3/utils/net_help.c | 10 ++ source3/utils/net_status.c | 257 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 source3/utils/net_status.c diff --git a/source3/Makefile.in b/source3/Makefile.in index dd8aaee6c4..d225b88f41 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -506,7 +506,8 @@ CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \ utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \ utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \ - utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o + utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \ + utils/net_status.o NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ diff --git a/source3/utils/net.c b/source3/utils/net.c index 75fa607cae..4d2b1eb439 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -616,6 +616,7 @@ static struct functable net_func[] = { {"GETDOMAINSID", net_getdomainsid}, {"MAXRID", net_maxrid}, {"IDMAP", net_idmap}, + {"STATUS", net_status}, #ifdef WITH_FAKE_KASERVER {"AFSKEY", net_afskey}, #endif diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index 514cf1af1b..e444978ea8 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -149,6 +149,15 @@ int net_help_file(int argc, const char **argv) return -1; } +int net_help_status(int argc, const char **argv) +{ + d_printf(" net status sessions [parseable]" + "\t\t\tShow list of open sessions\n"); + d_printf(" net status shares [parseable]" + "\t\t\tShow list of open shares\n"); + return -1; +} + static int net_usage(int argc, const char **argv) { d_printf(" net time\t\tto view or set time information\n"\ @@ -162,6 +171,7 @@ static int net_usage(int argc, const char **argv) " net setlocalsid SID\tto set the local domain SID\n"\ " net changesecretpw\tto change the machine password in the local secrets database only\n"\ " \tthis requires the -f flag as a safety barrier\n"\ + " net status\t\tShow server status\n"\ "\n"\ " net ads \tto run ADS commands\n"\ " net rap \tto run RAP (pre-RPC) commands\n"\ diff --git a/source3/utils/net_status.c b/source3/utils/net_status.c new file mode 100644 index 0000000000..0543f457cf --- /dev/null +++ b/source3/utils/net_status.c @@ -0,0 +1,257 @@ +/* + Samba Unix/Linux SMB client library + net status command -- possible replacement for smbstatus + Copyright (C) 2003 Volker Lendecke (vl@samba.org) + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "includes.h" +#include "../utils/net.h" + +static int show_session(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, + void *state) +{ + BOOL *parseable = (BOOL *)state; + struct sessionid sessionid; + + if (dbuf.dsize != sizeof(sessionid)) + return 0; + + memcpy(&sessionid, dbuf.dptr, sizeof(sessionid)); + + if (!process_exists(sessionid.pid)) { + return 0; + } + + if (*parseable) { + d_printf("%d\\%s\\%s\\%s\\%s\n", + (int)sessionid.pid, uidtoname(sessionid.uid), + gidtoname(sessionid.gid), + sessionid.remote_machine, sessionid.hostname); + } else { + d_printf("%5d %-12s %-12s %-12s (%s)\n", + (int)sessionid.pid, uidtoname(sessionid.uid), + gidtoname(sessionid.gid), + sessionid.remote_machine, sessionid.hostname); + } + + return 0; +} + +static int net_status_sessions(int argc, const char **argv) +{ + TDB_CONTEXT *tdb; + BOOL parseable; + + if (argc == 0) { + parseable = False; + } else if ((argc == 1) && strequal(argv[0], "parseable")) { + parseable = True; + } else { + return net_help_status(argc, argv); + } + + if (!parseable) { + d_printf("PID Username Group Machine" + " \n"); + d_printf("-------------------------------------------" + "------------------------\n"); + } + + tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, + TDB_DEFAULT, O_RDONLY, 0); + + if (tdb == NULL) { + d_printf("%s not initialised\n", lock_path("sessionid.tdb")); + return -1; + } + + tdb_traverse(tdb, show_session, &parseable); + tdb_close(tdb); + + return 0; +} + +static int show_share(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, + void *state) +{ + struct connections_data crec; + + if (dbuf.dsize != sizeof(crec)) + return 0; + + memcpy(&crec, dbuf.dptr, sizeof(crec)); + + if (crec.cnum == -1) + return 0; + + if (!process_exists(crec.pid)) { + return 0; + } + + d_printf("%-10.10s %5d %-12s %s", + crec.name,(int)crec.pid, + crec.machine, + asctime(LocalTime(&crec.start))); + + return 0; +} + +struct sessionids { + int num_entries; + struct sessionid *entries; +}; + +static int collect_pid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, + void *state) +{ + struct sessionids *ids = (struct sessionids *)state; + struct sessionid sessionid; + + if (dbuf.dsize != sizeof(sessionid)) + return 0; + + memcpy(&sessionid, dbuf.dptr, sizeof(sessionid)); + + if (!process_exists(sessionid.pid)) + return 0; + + ids->num_entries += 1; + ids->entries = Realloc(ids->entries, + sizeof(struct sessionid) * ids->num_entries); + ids->entries[ids->num_entries-1] = sessionid; + + return 0; +} + +static int show_share_parseable(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, + void *state) +{ + struct sessionids *ids = (struct sessionids *)state; + struct connections_data crec; + int i; + BOOL guest = True; + + if (dbuf.dsize != sizeof(crec)) + return 0; + + memcpy(&crec, dbuf.dptr, sizeof(crec)); + + if (crec.cnum == -1) + return 0; + + if (!process_exists(crec.pid)) { + return 0; + } + + for (i=0; inum_entries; i++) { + if (ids->entries[i].pid == crec.pid) { + guest = False; + break; + } + } + + d_printf("%s\\%d\\%s\\%s\\%s\\%s\\%s", + crec.name,(int)crec.pid, + guest ? "" : uidtoname(ids->entries[i].uid), + guest ? "" : gidtoname(ids->entries[i].gid), + crec.machine, + guest ? "" : ids->entries[i].hostname, + asctime(LocalTime(&crec.start))); + + return 0; +} + +static int net_status_shares_parseable(int argc, const char **argv) +{ + struct sessionids ids; + TDB_CONTEXT *tdb; + + ids.num_entries = 0; + ids.entries = NULL; + + tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, + TDB_DEFAULT, O_RDONLY, 0); + + if (tdb == NULL) { + d_printf("%s not initialised\n", lock_path("sessionid.tdb")); + return -1; + } + + tdb_traverse(tdb, collect_pid, &ids); + tdb_close(tdb); + + tdb = tdb_open_log(lock_path("connections.tdb"), 0, + TDB_DEFAULT, O_RDONLY, 0); + + if (tdb == NULL) { + d_printf("%s not initialised\n", lock_path("connections.tdb")); + d_printf("This is normal if no SMB client has ever connected " + "to your server.\n"); + return -1; + } + + tdb_traverse(tdb, show_share_parseable, &ids); + tdb_close(tdb); + + SAFE_FREE(ids.entries); + + return 0; +} + +static int net_status_shares(int argc, const char **argv) +{ + TDB_CONTEXT *tdb; + + if (argc == 0) { + + d_printf("\nService pid machine " + "Connected at\n"); + d_printf("-------------------------------------" + "------------------\n"); + + tdb = tdb_open_log(lock_path("connections.tdb"), 0, + TDB_DEFAULT, O_RDONLY, 0); + + if (tdb == NULL) { + d_printf("%s not initialised\n", + lock_path("connections.tdb")); + d_printf("This is normal if no SMB client has ever " + "connected to your server.\n"); + return -1; + } + + tdb_traverse(tdb, show_share, NULL); + tdb_close(tdb); + + return 0; + } + + if ((argc != 1) || !strequal(argv[0], "parseable")) { + return net_help_status(argc, argv); + } + + return net_status_shares_parseable(argc, argv); +} + +int net_status(int argc, const char **argv) +{ + struct functable func[] = { + {"sessions", net_status_sessions}, + {"shares", net_status_shares}, + {NULL, NULL} + }; + return net_run_function(argc, argv, func, net_help_status); +} -- cgit From 925876950124eefe673089c34d86c72b3180b04c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 1 Dec 2003 14:08:15 +0000 Subject: Beautify the net status help message a bit Volker (This used to be commit f8ffa207e05920f28502b45b550a394aba9648a7) --- source3/utils/net_help.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index e444978ea8..38261be90a 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -151,10 +151,10 @@ int net_help_file(int argc, const char **argv) int net_help_status(int argc, const char **argv) { - d_printf(" net status sessions [parseable]" - "\t\t\tShow list of open sessions\n"); - d_printf(" net status shares [parseable]" - "\t\t\tShow list of open shares\n"); + d_printf(" net status sessions [parseable] " + "Show list of open sessions\n"); + d_printf(" net status shares [parseable] " + "Show list of open shares\n"); return -1; } -- cgit From 1ccd951fafeed7e899d84846264b4ed63a251322 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 1 Dec 2003 14:13:20 +0000 Subject: In the brief 'net rpc group' listing, don't cut off group names at 21 chars. Volker (This used to be commit d623f695c48736f21a79f02cf669d5bcf39cd920) --- source3/utils/net_rpc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 75b3726b44..04a0330774 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -989,7 +989,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, printf("%-21.21s %-50.50s\n", group, desc); else - printf("%-21.21s\n", group); + printf("%s\n", group); } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); /* query domain aliases */ @@ -1030,7 +1030,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, groups[i].acct_name, description); } else { - printf("%-21.21s\n", groups[i].acct_name); + printf("%s\n", groups[i].acct_name); } } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); @@ -1081,7 +1081,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, groups[i].acct_name, description); } else { - printf("%-21.21s\n", groups[i].acct_name); + printf("%s\n", groups[i].acct_name); } } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); -- cgit From 905a32a5adc4aaad7395abcfd48b1adf1065abf5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 1 Dec 2003 18:02:30 +0000 Subject: don't mistake pre-existing UNIX jobs for smb jobs; patch from SATOH Fumiyasu bug 770 (This used to be commit d6333ae8d707c17a6fa26a39b14a802bc816ab3f) --- source3/printing/printing.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a4949f78e9..791c41fe69 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -612,12 +612,14 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid) pj.status = q->status; pj.size = q->size; pj.spooled = True; - pj.smbjob = (old_pj != NULL ? True : False); fstrcpy(pj.filename, old_pj ? old_pj->filename : ""); - if (jobid < UNIX_JOB_START) + if (jobid < UNIX_JOB_START) { + pj.smbjob = (old_pj != NULL ? True : False); fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document"); - else + } else { + pj.smbjob = False; fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file); + } fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user); fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum)); -- cgit From 6c41d202d1eeff5f7687c23cd5e5d6271d3b5ca0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 1 Dec 2003 18:38:08 +0000 Subject: add Replicator and RAS Servers to list of builtin SIDs we resolve; bug 608 (This used to be commit 1bb2281e177d1f312c0c3c117c5b0dcabe57125b) --- source3/passdb/util_sam_sid.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c index 6a7675a12a..c4fd08746c 100644 --- a/source3/passdb/util_sam_sid.c +++ b/source3/passdb/util_sam_sid.c @@ -76,6 +76,8 @@ static const known_sid_users builtin_groups[] = { { BUILTIN_ALIAS_RID_SYSTEM_OPS, SID_NAME_ALIAS, "Server Operators" }, { BUILTIN_ALIAS_RID_PRINT_OPS, SID_NAME_ALIAS, "Print Operators" }, { BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" }, + { BUILTIN_ALIAS_RID_REPLICATOR, SID_NAME_ALIAS, "Replicator" }, + { BUILTIN_ALIAS_RID_RAS_SERVERS, SID_NAME_ALIAS, "RAS Servers" }, { 0, (enum SID_NAME_USE)0, NULL}}; /************************************************************************** -- cgit From 156d15b93b6940faa38b06fd52add0b3e53a8ad3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 1 Dec 2003 19:26:32 +0000 Subject: fix inverted logic caused by s/strcmp/strequal/; host allow/deny works again; bug 846 (This used to be commit 18fe1681c15cc25a41e738e615b759d759f9ecf4) --- source3/lib/access.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/access.c b/source3/lib/access.c index a642a92d71..81eab7c738 100644 --- a/source3/lib/access.c +++ b/source3/lib/access.c @@ -114,7 +114,7 @@ static BOOL string_match(const char *tok,const char *s, char *invalid_char) } else if (strequal(tok, "LOCAL")) { /* local: no dots */ if (strchr_m(s, '.') == 0 && !strequal(s, "unknown")) return (True); - } else if (!strequal(tok, s)) { /* match host name or address */ + } else if (strequal(tok, s)) { /* match host name or address */ return (True); } else if (tok[(tok_len = strlen(tok)) - 1] == '.') { /* network */ if (strncmp(tok, s, tok_len) == 0) -- cgit From 8ecfda5c07255365e67f760a2a5be651ace6518b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 1 Dec 2003 19:58:53 +0000 Subject: another strequal() == 0 fix (This used to be commit 818bba4b796440453e5911369adf5bd147e9b961) --- source3/passdb/util_sam_sid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c index c4fd08746c..6e9ccecc9e 100644 --- a/source3/passdb/util_sam_sid.c +++ b/source3/passdb/util_sam_sid.c @@ -292,7 +292,7 @@ BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char continue; for (j=0; users[j].known_user_name != NULL; j++) { - if (strequal(users[j].known_user_name, name) == 0) { + if ( strequal(users[j].known_user_name, name) ) { sid_copy(sid, sid_name_map[i].sid); sid_append_rid(sid, users[j].rid); *use = users[j].sid_name_use; -- cgit From b91cff3fc5ccb9b08336c89e1a1e94959e15ee88 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 22:46:49 +0000 Subject: Get a little paranoid about memfree use in convert_string_allocate.. Looking at crash bugs #809 and others. Jeremy. (This used to be commit e122891bebd33fc7bd654146a5cbec1feb307555) --- source3/lib/charcnv.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 9d15c6daa0..d6eb336d31 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -488,7 +488,6 @@ convert: } } - /** * Convert between character sets, allocating a new buffer using talloc for the result. * @@ -581,19 +580,19 @@ char *strdup_upper(const char *s) size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) { size_t size; - smb_ucs2_t *buffer; + smb_ucs2_t *buffer = NULL; size = convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, srclen, (void **) &buffer); - if (size == -1) { + if (size == -1 || !buffer) { smb_panic("failed to create UCS2 buffer"); } if (!strlower_w(buffer) && (dest == src)) { - free(buffer); + SAFE_FREE(buffer); return srclen; } size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen); - free(buffer); + SAFE_FREE(buffer); return size; } @@ -604,11 +603,11 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) char *strdup_lower(const char *s) { size_t size; - smb_ucs2_t *buffer; + smb_ucs2_t *buffer = NULL; char *out_buffer; size = push_ucs2_allocate(&buffer, s); - if (size == -1) { + if (size == -1 || !buffer) { return NULL; } -- cgit From 6eed4ed9adbdce228b6e239fa0c4bb3f21d25f1f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 22:55:41 +0000 Subject: Client connect signing error messages should be level zero else they're easy to miss. Jeremy. (This used to be commit b5f32a0869017a3ce457bf45e4aa2c1b621162c6) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a920a1b7ff..f6dfd40006 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1021,7 +1021,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) { - DEBUG(1,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); + DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); return False; } @@ -1057,7 +1057,7 @@ BOOL cli_negprot(struct cli_state *cli) if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { /* Fail if server says signing is mandatory and we don't want to support it. */ if (!cli->sign_info.allow_smb_signing) { - DEBUG(1,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); + DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); return False; } cli->sign_info.negotiated_smb_signing = True; -- cgit From f09e4312f0b838e36f1ff0c0188a941c187ebad8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 2 Dec 2003 11:41:42 +0000 Subject: Two trivial warnings Volker (This used to be commit 6b46ee6fd5c47d04e9c61e6cec3f0b16b268cd2d) --- source3/torture/nbio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/torture/nbio.c b/source3/torture/nbio.c index 6c51db3cf3..2e79584d23 100644 --- a/source3/torture/nbio.c +++ b/source3/torture/nbio.c @@ -52,7 +52,7 @@ double nbio_total(void) return total; } -void nb_alarm(void) +void nb_alarm(int ignore) { int i; int lines=0, num_clients=0; @@ -79,6 +79,7 @@ void nbio_shmem(int n) } } +#if 0 static int ne_find_handle(int handle) { int i; @@ -88,6 +89,7 @@ static int ne_find_handle(int handle) } return -1; } +#endif static int find_handle(int handle) { -- cgit From f0f1e99fedbca99ede6e95758bc7088ad2106748 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Dec 2003 23:16:24 +0000 Subject: Fix for "hash" (not hash2) type mangling. Noticed by "Forrest W. Christian" Jeremy. (This used to be commit b2d63007608944fff05e45b1f6b312373d022062) --- source3/smbd/mangle_hash.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source3/smbd/mangle_hash.c b/source3/smbd/mangle_hash.c index ac2d7681e8..16722ae6e9 100644 --- a/source3/smbd/mangle_hash.c +++ b/source3/smbd/mangle_hash.c @@ -139,7 +139,7 @@ extern BOOL case_mangle; /* If true, all chars in 8.3 should be same case. */ /* -------------------------------------------------------------------- */ -static NTSTATUS has_valid_chars(const smb_ucs2_t *s, BOOL allow_wildcards) +static NTSTATUS has_valid_83_chars(const smb_ucs2_t *s, BOOL allow_wildcards) { if (!s || !*s) return NT_STATUS_INVALID_PARAMETER; @@ -176,7 +176,7 @@ static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **pr if ((p = strrchr_w(*prefix, UCS2_CHAR('.')))) { ext_len = strlen_w(p+1); if ((ext_len > 0) && (ext_len < 4) && (p != *prefix) && - (NT_STATUS_IS_OK(has_valid_chars(p+1,allow_wildcards)))) /* check extension */ { + (NT_STATUS_IS_OK(has_valid_83_chars(p+1,allow_wildcards)))) /* check extension */ { *p = 0; *extension = strdup_w(p+1); if (!*extension) { @@ -200,7 +200,7 @@ static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **pr * ************************************************************************** ** */ -static NTSTATUS is_valid_name(const smb_ucs2_t *fname, BOOL allow_wildcards) +static NTSTATUS is_valid_name(const smb_ucs2_t *fname, BOOL allow_wildcards, BOOL only_8_3) { smb_ucs2_t *str, *p; NTSTATUS ret = NT_STATUS_OK; @@ -216,9 +216,11 @@ static NTSTATUS is_valid_name(const smb_ucs2_t *fname, BOOL allow_wildcards) if (*fname == UCS2_CHAR('.')) return NT_STATUS_UNSUCCESSFUL; - ret = has_valid_chars(fname, allow_wildcards); - if (!NT_STATUS_IS_OK(ret)) - return ret; + if (only_8_3) { + ret = has_valid_83_chars(fname, allow_wildcards); + if (!NT_STATUS_IS_OK(ret)) + return ret; + } str = strdup_w(fname); p = strchr_w(str, UCS2_CHAR('.')); @@ -286,7 +288,7 @@ static NTSTATUS is_8_3_w(const smb_ucs2_t *fname, BOOL allow_wildcards) if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0) return NT_STATUS_OK; - if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards))) + if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards, True))) goto done; if (!NT_STATUS_IS_OK(mangle_get_prefix(fname, &pref, &ext, allow_wildcards))) @@ -737,7 +739,7 @@ static void name_map(char *OutName, BOOL need83, BOOL cache83) return; } - if( !need83 && !NT_STATUS_IS_OK(is_valid_name(OutName_ucs2, False))) + if( !need83 && !NT_STATUS_IS_OK(is_valid_name(OutName_ucs2, False, False))) need83 = True; /* check if it's already in 8.3 format */ -- cgit From 3a1dd0dc773c98c7af40de07cd6e43b5f3170280 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 4 Dec 2003 04:08:32 +0000 Subject: * fix RemoveSidForeignDomain() ; bug 252 * don't fall back to unmapped UNIX group for get_local_group_from_sid() * remove an extra become/unbecome_root() pair from group enumeration (This used to be commit c0f34b42a6a4af09ae4b76721bc350784d87f686) --- source3/groupdb/mapping.c | 30 ++++----- source3/include/rpc_samr.h | 14 ++--- source3/rpc_parse/parse_samr.c | 12 ++-- source3/rpc_server/srv_samr.c | 20 +++--- source3/rpc_server/srv_samr_nt.c | 127 +++++++++++++++++++++++++-------------- source3/rpc_server/srv_util.c | 2 +- 6 files changed, 121 insertions(+), 84 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 8f534d779e..b1c260581e 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -547,27 +547,28 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) { - struct group *grp; - if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping")); return(False); } /* The group is in the mapping table */ - if(pdb_getgrsid(map, sid)) { - if (map->sid_name_use!=SID_NAME_ALIAS) { - return False; - } + + if( !pdb_getgrsid(map, sid) ) + return False; - if (map->gid==-1) { - return False; - } - - if ( (grp=getgrgid(map->gid)) == NULL) { - return False; - } - } else { + if ( (map->sid_name_use != SID_NAME_ALIAS) + || (map->gid == -1) + || (getgrgid(map->gid) == NULL) ) + { + return False; + } + +#if 0 /* JERRY */ + /* local groups only exist in the group mapping DB so this + is not necessary */ + + else { /* the group isn't in the mapping table. * make one based on the unix information */ uint32 alias_rid; @@ -588,6 +589,7 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) sid_copy(&map->sid, &sid); } +#endif return True; } diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index 3b81042df3..787535d0e9 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -127,7 +127,7 @@ SamrTestPrivateFunctionsUser #define SAMR_UNKNOWN_2a 0x2a #define SAMR_UNKNOWN_2b 0x2b #define SAMR_GET_USRDOM_PWINFO 0x2c -#define SAMR_REMOVE_USER_FOREIGN_DOMAIN 0x2d +#define SAMR_REMOVE_SID_FOREIGN_DOMAIN 0x2d #define SAMR_UNKNOWN_2E 0x2e /* looks like an alias for SAMR_QUERY_DOMAIN_INFO */ #define SAMR_UNKNOWN_2f 0x2f #define SAMR_QUERY_DISPINFO3 0x30 /* Alias for SAMR_QUERY_DISPINFO @@ -1790,21 +1790,21 @@ typedef struct r_samr_chgpasswd_user_info } SAMR_R_CHGPASSWD_USER; -/* SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN */ -typedef struct q_samr_remove_user_foreign_domain_info +/* SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN */ +typedef struct q_samr_remove_sid_foreign_domain_info { POLICY_HND dom_pol; /* policy handle */ DOM_SID2 sid; /* SID */ -} SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN; +} SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN; -/* SAMR_R_REMOVE_USER_FOREIGN_DOMAIN */ -typedef struct r_samr_remove_user_foreign_domain_info +/* SAMR_R_REMOVE_SID_FOREIGN_DOMAIN */ +typedef struct r_samr_remove_sid_foreign_domain_info { NTSTATUS status; /* return status */ -} SAMR_R_REMOVE_USER_FOREIGN_DOMAIN; +} SAMR_R_REMOVE_SID_FOREIGN_DOMAIN; diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 5e3502b242..607c9ecf64 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -181,9 +181,9 @@ BOOL samr_io_r_lookup_domain(const char *desc, SAMR_R_LOOKUP_DOMAIN * r_u, reads or writes a structure. ********************************************************************/ -void init_samr_q_remove_user_foreign_domain(SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN * q_u, POLICY_HND *dom_pol, DOM_SID *sid) +void init_samr_q_remove_sid_foreign_domain(SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN * q_u, POLICY_HND *dom_pol, DOM_SID *sid) { - DEBUG(5, ("samr_init_samr_q_remove_user_foreign_domain\n")); + DEBUG(5, ("samr_init_samr_q_remove_sid_foreign_domain\n")); q_u->dom_pol = *dom_pol; init_dom_sid2(&q_u->sid, sid); @@ -193,13 +193,13 @@ void init_samr_q_remove_user_foreign_domain(SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN * reads or writes a structure. ********************************************************************/ -BOOL samr_io_q_remove_user_foreign_domain(const char *desc, SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN * q_u, +BOOL samr_io_q_remove_sid_foreign_domain(const char *desc, SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN * q_u, prs_struct *ps, int depth) { if (q_u == NULL) return False; - prs_debug(ps, depth, desc, "samr_io_q_remove_user_foreign_domain"); + prs_debug(ps, depth, desc, "samr_io_q_remove_sid_foreign_domain"); depth++; if(!prs_align(ps)) @@ -221,13 +221,13 @@ BOOL samr_io_q_remove_user_foreign_domain(const char *desc, SAMR_Q_REMOVE_USER_F reads or writes a structure. ********************************************************************/ -BOOL samr_io_r_remove_user_foreign_domain(const char *desc, SAMR_R_REMOVE_USER_FOREIGN_DOMAIN * r_u, +BOOL samr_io_r_remove_sid_foreign_domain(const char *desc, SAMR_R_REMOVE_SID_FOREIGN_DOMAIN * r_u, prs_struct *ps, int depth) { if (r_u == NULL) return False; - prs_debug(ps, depth, desc, "samr_io_r_remove_user_foreign_domain"); + prs_debug(ps, depth, desc, "samr_io_r_remove_sid_foreign_domain"); depth++; if(!prs_align(ps)) diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index a0f62c20fc..971f5ed40c 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -1343,13 +1343,13 @@ static BOOL api_samr_open_group(pipes_struct *p) } /******************************************************************* - api_samr_remove_user_foreign_domain + api_samr_remove_sid_foreign_domain ********************************************************************/ -static BOOL api_samr_remove_user_foreign_domain(pipes_struct *p) +static BOOL api_samr_remove_sid_foreign_domain(pipes_struct *p) { - SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN q_u; - SAMR_R_REMOVE_USER_FOREIGN_DOMAIN r_u; + SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN q_u; + SAMR_R_REMOVE_SID_FOREIGN_DOMAIN r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; @@ -1357,15 +1357,15 @@ static BOOL api_samr_remove_user_foreign_domain(pipes_struct *p) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - if (!samr_io_q_remove_user_foreign_domain("", &q_u, data, 0)) { - DEBUG(0,("api_samr_remove_user_foreign_domain: unable to unmarshall SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN.\n")); + if (!samr_io_q_remove_sid_foreign_domain("", &q_u, data, 0)) { + DEBUG(0,("api_samr_remove_sid_foreign_domain: unable to unmarshall SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN.\n")); return False; } - r_u.status = _samr_remove_user_foreign_domain(p, &q_u, &r_u); + r_u.status = _samr_remove_sid_foreign_domain(p, &q_u, &r_u); - if (!samr_io_r_remove_user_foreign_domain("", &r_u, rdata, 0)) { - DEBUG(0,("api_samr_remove_user_foreign_domain: unable to marshall SAMR_R_REMOVE_USER_FOREIGN_DOMAIN.\n")); + if (!samr_io_r_remove_sid_foreign_domain("", &r_u, rdata, 0)) { + DEBUG(0,("api_samr_remove_sid_foreign_domain: unable to marshall SAMR_R_REMOVE_SID_FOREIGN_DOMAIN.\n")); return False; } @@ -1483,7 +1483,7 @@ static struct api_struct api_samr_cmds [] = {"SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias }, {"SAMR_OPEN_GROUP" , SAMR_OPEN_GROUP , api_samr_open_group }, {"SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain }, - {"SAMR_REMOVE_USER_FOREIGN_DOMAIN" , SAMR_REMOVE_USER_FOREIGN_DOMAIN , api_samr_remove_user_foreign_domain }, + {"SAMR_REMOVE_SID_FOREIGN_DOMAIN" , SAMR_REMOVE_SID_FOREIGN_DOMAIN , api_samr_remove_sid_foreign_domain }, {"SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain }, {"SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj }, diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index d3da830991..7be9b41ee9 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -1384,8 +1384,6 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid))); - become_root(); /* local_lookup_name can require root privs */ - for (i = 0; i < num_rids; i++) { fstring name; DOM_SID sid; @@ -1421,8 +1419,6 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO } } - unbecome_root(); - init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status); DEBUG(5,("_samr_lookup_names: %d\n", __LINE__)); @@ -4250,75 +4246,114 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G } /********************************************************************* - _samr_remove_user_foreign_domain + _samr_remove_sid_foreign_domain *********************************************************************/ -NTSTATUS _samr_remove_user_foreign_domain(pipes_struct *p, - SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *q_u, - SAMR_R_REMOVE_USER_FOREIGN_DOMAIN *r_u) +NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, + SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u, + SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u) { - DOM_SID user_sid, dom_sid; + DOM_SID delete_sid, alias_sid; SAM_ACCOUNT *sam_pass=NULL; uint32 acc_granted; + GROUP_MAP map; + BOOL is_user = False; + NTSTATUS result; + enum SID_NAME_USE type = SID_NAME_UNKNOWN; - sid_copy( &user_sid, &q_u->sid.sid ); + sid_copy( &delete_sid, &q_u->sid.sid ); - DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n", - sid_string_static(&user_sid))); + DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n", + sid_string_static(&delete_sid))); /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted)) return NT_STATUS_INVALID_HANDLE; + + result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, + "_samr_remove_sid_foreign_domain"); - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, - STD_RIGHT_DELETE_ACCESS, "_samr_remove_user_foreign_domain"))) - { - return r_u->status; - } + if (!NT_STATUS_IS_OK(result)) + return result; + + DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n", + sid_string_static(&alias_sid))); - if ( !sid_check_is_in_our_domain(&user_sid) ) { - DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n")); - return NT_STATUS_NO_SUCH_USER; + /* make sure we can handle this */ + + if ( sid_check_is_domain(&alias_sid) ) + type = SID_NAME_DOM_GRP; + else if ( sid_check_is_builtin(&alias_sid) ) + type = SID_NAME_ALIAS; + + if ( type == SID_NAME_UNKNOWN ) { + DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n")); + return NT_STATUS_OK; } /* check if the user exists before trying to delete */ pdb_init_sam(&sam_pass); - if ( !pdb_getsampwsid(sam_pass, &user_sid) ) { + if ( pdb_getsampwsid(sam_pass, &delete_sid) ) { + is_user = True; + } else { + /* maybe it is a group */ + if( !pdb_getgrsid(&map, delete_sid) ) { + DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n", + sid_string_static(&delete_sid))); + result = NT_STATUS_INVALID_SID; + goto done; + } + } - DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n", - sid_string_static(&user_sid))); - - pdb_free_sam(&sam_pass); + /* we can only delete a user from a group since we don't have + nested groups anyways. So in the latter case, just say OK */ + + if ( is_user ) { + GROUP_MAP *mappings = NULL; + uint32 num_groups, i; + struct group *grp2; - return NT_STATUS_NO_SUCH_USER; - } + if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) { + + /* interate over the groups */ + for ( i=0; igr_name) ) + continue; + + smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass)); + + if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) { + /* should we fail here ? */ + DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n", + pdb_get_username(sam_pass), grp2->gr_name )); + continue; + } + + DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n", + pdb_get_username(sam_pass), grp2->gr_name )); + } + + SAFE_FREE(mappings); + } } + result = NT_STATUS_OK; +done: + pdb_free_sam(&sam_pass); - return NT_STATUS_OK; + return result; } /******************************************************************* diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index d5b87b7c10..c2395e6fae 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -382,7 +382,7 @@ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SA done: *pgids=gids; *numgroups=cur_gid; - safe_free(map); + SAFE_FREE(map); return True; } -- cgit From 555ef2d5cfab6b5cac69f943d5ea870dd0c94423 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 4 Dec 2003 04:32:22 +0000 Subject: don't crash on a NULL priviledge pointer; patch from Jianliang Lu (This used to be commit 5bbfa9989bcade2e1192a68596de3e574faed1d5) --- source3/lib/privileges.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c index 1ed583382d..b9d4df301d 100644 --- a/source3/lib/privileges.c +++ b/source3/lib/privileges.c @@ -69,6 +69,12 @@ NTSTATUS dupalloc_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR * { NTSTATUS ret; + /* don't crash if the source pointer is NULL (since we don't + do priviledges now anyways) */ + + if ( !old_la ) + return NT_STATUS_OK; + *new_la = (LUID_ATTR *)talloc(mem_ctx, sizeof(LUID_ATTR)); ALLOC_CHECK(new_la, ret, done, "dupalloc_luid_attr"); -- cgit From c6f0190b5418b1ee02fdd45b7c6e3ce560b834b8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 4 Dec 2003 04:52:49 +0000 Subject: support munged dial for ldapsam; patch from Aurélien Degrémont; bug 800 (This used to be commit acf9eae7b0c95776358292c3463951477575bcc6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/LDAP/samba.schema | 55 +++++----------------------------------------- source3/include/smbldap.h | 1 + source3/lib/smbldap.c | 1 + source3/passdb/pdb_ldap.c | 18 ++++++++++++--- 4 files changed, 23 insertions(+), 52 deletions(-) diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema index 79f5891651..3ec30c46d8 100644 --- a/examples/LDAP/samba.schema +++ b/examples/LDAP/samba.schema @@ -236,6 +236,11 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) +attributetype ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaMungedDial' + DESC '' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} ) + ## ## SID, of any type ## @@ -288,38 +293,6 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' - DESC 'Share Name' - EQUALITY caseIgnoreMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' - DESC 'Option Name' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) - -attributetype ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' - DESC 'A boolean option' - EQUALITY booleanMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' - DESC 'An integer option' - EQUALITY integerMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' - DESC 'A string option' - EQUALITY caseExactIA5Match - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption' - DESC 'A string list option' - EQUALITY caseIgnoreMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) - ####################################################################### ## objectClasses used by Samba 3.0 schema ## ####################################################################### @@ -340,7 +313,7 @@ objectclass ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ - sambaPrimaryGroupSID $ sambaDomainName )) + sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial)) ## ## Group mapping info @@ -375,19 +348,3 @@ objectclass ( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL DESC 'Structural Class for a SID' MUST ( sambaSID ) ) - - - -objectclass ( 1.3.6.1.4.1.7165.1.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY - DESC 'Samba Configuration Section' - MAY ( description ) ) - -objectclass ( 1.3.6.1.4.1.7165.1.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL - DESC 'Samba Share Section' - MUST ( sambaShareName ) - MAY ( description ) ) - -objectclass ( 1.3.6.1.4.1.7165.1.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL - DESC 'Samba Configuration Option' - MUST ( sambaOptionName ) - MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringListoption $ description ) ) diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 9765b9fbd6..17584c4fe4 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -90,6 +90,7 @@ #define LDAP_ATTR_NEXT_RID 34 #define LDAP_ATTR_BAD_PASSWORD_COUNT 35 #define LDAP_ATTR_LOGON_COUNT 36 +#define LDAP_ATTR_MUNGED_DIAL 37 typedef struct _attrib_map_entry { int attrib; diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index ac35ed2a03..7bd4c6d7aa 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -97,6 +97,7 @@ ATTRIB_MAP_ENTRY attrib_map_v30[] = { { LDAP_ATTR_DOMAIN, "sambaDomainName" }, { LDAP_ATTR_OBJCLASS, "objectClass" }, { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" }, + { LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" }, { LDAP_ATTR_LIST_END, NULL } }; diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 023e9f3fe0..4d7c7791bd 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -415,8 +415,8 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, logon_script, profile_path, acct_desc, - munged_dial, workstations; + char munged_dial[2048]; uint32 user_rid; uint8 smblmpwd[LM_HASH_LEN], smbntpwd[NT_HASH_LEN]; @@ -660,6 +660,13 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_workstations(sampass, workstations, PDB_SET); } + if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), munged_dial)) { + /* leave as default */; + } else { + pdb_set_munged_dial(sampass, munged_dial, PDB_SET); + } + /* FIXME: hours stuff should be cleaner */ logon_divs = 168; @@ -703,7 +710,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_hours_len(sampass, hours_len, PDB_SET); pdb_set_logon_divs(sampass, logon_divs, PDB_SET); - pdb_set_munged_dial(sampass, munged_dial, PDB_SET); +/* pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */ /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */ @@ -851,7 +858,12 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), pdb_get_workstations(sampass)); - + + if (need_update(sampass, PDB_MUNGEDDIAL)) + smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, + get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), + pdb_get_munged_dial(sampass)); + if (need_update(sampass, PDB_SMBHOME)) smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), -- cgit From f5eed76193bfd3655bf6162832fe2089c4b15f12 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 4 Dec 2003 05:02:25 +0000 Subject: readding schema items that were accidentally deleted (This used to be commit 14dd4403fe006345a9cdf55b2b35a31176463349) --- examples/LDAP/samba.schema | 50 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema index 3ec30c46d8..2f1b8e8ff2 100644 --- a/examples/LDAP/samba.schema +++ b/examples/LDAP/samba.schema @@ -236,7 +236,7 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) -attributetype ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaMungedDial' +attributetype ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC '' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} ) @@ -293,6 +293,38 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' + DESC 'Share Name' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' + DESC 'Option Name' + EQUALITY caseIgnoreMatch + SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' + DESC 'A boolean option' + EQUALITY booleanMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' + DESC 'An integer option' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' + DESC 'A string option' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption' + DESC 'A string list option' + EQUALITY caseIgnoreMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + ####################################################################### ## objectClasses used by Samba 3.0 schema ## ####################################################################### @@ -348,3 +380,19 @@ objectclass ( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL DESC 'Structural Class for a SID' MUST ( sambaSID ) ) + + + +objectclass ( 1.3.6.1.4.1.7165.1.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY + DESC 'Samba Configuration Section' + MAY ( description ) ) + +objectclass ( 1.3.6.1.4.1.7165.1.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL + DESC 'Samba Share Section' + MUST ( sambaShareName ) + MAY ( description ) ) + +objectclass ( 1.3.6.1.4.1.7165.1.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL + DESC 'Samba Configuration Option' + MUST ( sambaOptionName ) + MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringListoption $ description ) ) -- cgit From 708c22ab7ff999664c51c470e2fc969cee5f558d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 4 Dec 2003 16:39:11 +0000 Subject: typo in BASEDIR; patch from Darren Chew (This used to be commit c0710a34ba737ebdd078beb223df528b297057a1) --- packaging/Solaris/samba.server.master | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/Solaris/samba.server.master b/packaging/Solaris/samba.server.master index 6de77780b3..d8bea2421c 100755 --- a/packaging/Solaris/samba.server.master +++ b/packaging/Solaris/samba.server.master @@ -37,7 +37,7 @@ case "$1" in 'restart') killproc nmbd killproc smbd - BASE=/usr/local/samba + BASE=__BASEDIR__/samba $BASE/bin/smbd -D -s$BASE/lib/smb.conf $BASE/bin/nmbd -D -l$BASE/var/log -s$BASE/lib/smb.conf ;; -- cgit From 386e319ab58ba18150fc497796576ec5f9389feb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 4 Dec 2003 20:22:19 +0000 Subject: fix process_incoming_data() to return the number of bytes handled this call whether we have a complete pdu or not; fixes bug with multiple pdu request rpc's broken over SMBwriteX calls each (This used to be commit 514acc655d58a660b2a2542ff81a880f1bdfc3f6) --- source3/rpc_server/srv_pipe_hnd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index a9fd9ec652..514c22d471 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -772,6 +772,7 @@ static ssize_t process_complete_pdu(pipes_struct *p) static ssize_t process_incoming_data(pipes_struct *p, char *data, size_t n) { size_t data_to_copy = MIN(n, MAX_PDU_FRAG_LEN - p->in_data.pdu_received_len); + size_t old_pdu_received_len = p->in_data.pdu_received_len; DEBUG(10,("process_incoming_data: Start: pdu_received_len = %u, pdu_needed_len = %u, incoming data = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len, @@ -831,10 +832,11 @@ incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned /* * Do we have a complete PDU ? + * (return the nym of bytes handled in the call) */ if(p->in_data.pdu_received_len == p->in_data.pdu_needed_len) - return process_complete_pdu(p); + return process_complete_pdu(p) - old_pdu_received_len; DEBUG(10,("process_incoming_data: not a complete PDU yet. pdu_received_len = %u, pdu_needed_len = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len )); -- cgit From eb535b8574290cfdc48771be3d00a1403d596cf6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 Dec 2003 15:27:58 +0000 Subject: create libdir for installclientlib; patch from Bill Knox (This used to be commit 915b5eb67f8d4acc901d78b7b7d4d615aef817cd) --- source3/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/Makefile.in b/source3/Makefile.in index d225b88f41..a660718c37 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1261,6 +1261,7 @@ installswat: installdirs installmsg @$(SHELL) $(srcdir)/script/installswat.sh $(DESTDIR)$(SWATDIR) $(srcdir) installclientlib: installdirs libsmbclient + @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)${prefix}/lib -$(INSTALLCLIENTCMD_SH) bin/libsmbclient.@SHLIBEXT@ $(DESTDIR)${prefix}/lib -$(INSTALLCLIENTCMD_A) bin/libsmbclient.a $(DESTDIR)${prefix}/lib @$(SHELL) $(srcdir)/script/installdirs.sh $(DESTDIR)${prefix}/include -- cgit From feb51ad34192714ef7f0e9be8cf22725b25848de Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 Dec 2003 17:21:00 +0000 Subject: packaging updates from Buchan (This used to be commit 9a5b5be68e6ba2c3ab06eb4a8104b7d2d71f0c2a) --- packaging/Mandrake/samba2.spec.tmpl | 13 ++++++++++--- packaging/Mandrake/winbind.init | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packaging/Mandrake/samba2.spec.tmpl b/packaging/Mandrake/samba2.spec.tmpl index cff54d146b..127aee48d8 100644 --- a/packaging/Mandrake/samba2.spec.tmpl +++ b/packaging/Mandrake/samba2.spec.tmpl @@ -14,11 +14,12 @@ %define pkg_name samba %define ver 3.0.1pre3 -%define rel 3mdk +%define rel 5mdk %define vscanver 0.3.3beta1 %define libsmbmajor 0 -%{!?mklibname: %define mklibname %lib%{1}%{?2:%{2}}%{?3:_%{3}}%{-s:-static}%{-d:-devel}} +%{!?lib: %global lib lib} +%{!?mklibname: %global mklibname(ds) %lib%{1}%{?2:%{2}}%{?3:_%{3}}%{-s:-static}%{-d:-devel}} %define libname %mklibname smbclient %libsmbmajor @@ -1647,7 +1648,13 @@ update-alternatives --auto smbclient %exclude %{_mandir}/man1/smbsh*.1* %changelog -* Sun Nov 16 2003 Buchan Milne 3.0.1-0.rpe3.3mdk +* Fri Dec 05 2003 Buchan Milne 3.0.1-0.pre3.5mdk +- Allow winbind to start if old winbind ranges are used (ease upgrades) + +* Tue Nov 18 2003 Buchan Milne 3.0.1-0.pre3.4mdk +- Fix build as system on 8.2 (and probably earlier) + +* Sun Nov 16 2003 Buchan Milne 3.0.1-0.pre3.3mdk - Ensure printer drivers keep permissions by default (setgid and inherit perms) * Fri Nov 14 2003 Buchan Milne 3.0.1-0.pre3.2mdk diff --git a/packaging/Mandrake/winbind.init b/packaging/Mandrake/winbind.init index e5bc9adcbf..06e5b375d0 100644 --- a/packaging/Mandrake/winbind.init +++ b/packaging/Mandrake/winbind.init @@ -28,7 +28,7 @@ RETVAL=0 start() { echo -n "Starting Winbind services: " RETVAL=1 - if [ "`grep -i 'idmap uid' /etc/samba/smb.conf | egrep -v [\#\;]`" -a "`grep -i 'idmap gid' /etc/samba/smb.conf | egrep -v [\#\;]`" ]; then + if [ "`grep -i -E '(idmap|winbind) uid' /etc/samba/smb.conf | egrep -v [\#\;]`" -a "`grep -i -E '(idmap|winbind) gid' /etc/samba/smb.conf | egrep -v [\#\;]`" ]; then daemon winbindd RETVAL=$? else -- cgit From 24be4082d581e8594c867a04922035ef4ad0cdaa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Dec 2003 21:01:23 +0000 Subject: Janitor for tridge... Jeremy. (This used to be commit d9790a76d88b8c46d665f2294878ee13d438b791) --- source3/rpc_parse/parse_net.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index ad0a91e7ea..5df75fc5f6 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -2283,12 +2283,12 @@ static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * inf if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members)) return False; + if (ps->data_offset + 16 > ps->buffer_size) + return False; + ps->data_offset += 16; + if (info->ptr_members != 0) { - if (ps->data_offset + 16 > ps->buffer_size) - return False; - ps->data_offset += 16; - if (!prs_uint32("num_sids", ps, depth, &info->num_sids)) return False; if (info->num_sids != info->num_members) -- cgit From 7bec01c890b562e312be20a52379e9056bded3d2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 Dec 2003 21:52:17 +0000 Subject: fix %a variable for Windows 2003 -> Win2K3 (This used to be commit d7db1439a626ae13b77dc262c82e713fcab1ab4f) --- source3/lib/util.c | 24 ++++++++++++++---------- source3/smbd/sesssetup.c | 48 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/source3/lib/util.c b/source3/lib/util.c index 39515c6599..4f4e0eb5d7 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1751,13 +1751,15 @@ BOOL is_myworkgroup(const char *s) Win2k => "Windows 2000 5.0" NT4 => "Windows NT 4.0" Win9x => "Windows 4.0" + Windows 2003 doesn't set the native lan manager string but + they do set the domain to "Windows 2003 5.2" (probably a bug). ********************************************************************/ void ra_lanman_string( const char *native_lanman ) { - if ( 0 == strcmp( native_lanman, "Windows 2002 5.1" ) ) + if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 ) set_remote_arch( RA_WINXP ); - else if ( 0 == strcmp( native_lanman, "Windows .NET 5.2" ) ) + else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 ) set_remote_arch( RA_WIN2K3 ); } @@ -1772,33 +1774,35 @@ void set_remote_arch(enum remote_arch_types type) switch( type ) { case RA_WFWG: fstrcpy(remote_arch, "WfWg"); - return; + break; case RA_OS2: fstrcpy(remote_arch, "OS2"); - return; + break; case RA_WIN95: fstrcpy(remote_arch, "Win95"); - return; + break; case RA_WINNT: fstrcpy(remote_arch, "WinNT"); - return; + break; case RA_WIN2K: fstrcpy(remote_arch, "Win2K"); - return; + break; case RA_WINXP: fstrcpy(remote_arch, "WinXP"); - return; + break; case RA_WIN2K3: fstrcpy(remote_arch, "Win2K3"); - return; + break; case RA_SAMBA: fstrcpy(remote_arch,"Samba"); - return; + break; default: ra_type = RA_UNKNOWN; fstrcpy(remote_arch, "UNKNOWN"); break; } + + DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n", remote_arch)); } /******************************************************************* diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index ec01a330ee..da48c81fc1 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -463,7 +463,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, DATA_BLOB blob1; int ret; size_t bufrem; - fstring native_os, native_lanman; + fstring native_os, native_lanman, primary_domain; char *p2; uint16 data_blob_len = SVAL(inbuf, smb_vwv7); enum remote_arch_types ra_type = get_remote_arch(); @@ -497,11 +497,20 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, p2 = inbuf + smb_vwv13 + data_blob_len; p2 += srvstr_pull_buf(inbuf, native_os, p2, sizeof(native_os), STR_TERMINATE); p2 += srvstr_pull_buf(inbuf, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE); - DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s]\n", native_os, native_lanman)); - - if ( ra_type == RA_WIN2K ) - ra_lanman_string( native_lanman ); + p2 += srvstr_pull_buf(inbuf, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE); + DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", + native_os, native_lanman, primary_domain)); + if ( ra_type == RA_WIN2K ) { + /* Windows 2003 doesn't set the native lanman string, + but does set primary domain which is a bug I think */ + + if ( !strlen(native_lanman) ) + ra_lanman_string( primary_domain ); + else + ra_lanman_string( native_lanman ); + } + if (blob1.data[0] == ASN1_APPLICATION(0)) { /* its a negTokenTarg packet */ ret = reply_spnego_negotiate(conn, inbuf, outbuf, length, bufsize, blob1); @@ -556,6 +565,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, fstring domain; fstring native_os; fstring native_lanman; + fstring primary_domain; static BOOL done_sesssetup = False; extern BOOL global_encrypted_passwords_negotiated; extern BOOL global_spnego_negotiated; @@ -619,6 +629,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, uint16 passlen2 = SVAL(inbuf,smb_vwv8); enum remote_arch_types ra_type = get_remote_arch(); char *p = smb_buf(inbuf); + char *save_p = smb_buf(inbuf); + uint16 byte_count; + if(global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv11); @@ -689,11 +702,28 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, p += srvstr_pull_buf(inbuf, domain, p, sizeof(domain), STR_TERMINATE); p += srvstr_pull_buf(inbuf, native_os, p, sizeof(native_os), STR_TERMINATE); p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE); - DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n", - domain,native_os,native_lanman)); - if ( ra_type == RA_WIN2K ) - ra_lanman_string( native_lanman ); + /* not documented or decoded by Ethereal but there is one more string + in the extra bytes which is the same as the PrimaryDomain when using + extended security. Windows NT 4 and 2003 use this string to store + the native lanman string. Windows 9x does not include a string here + at all so we have to check if we have any extra bytes left */ + + byte_count = SVAL(inbuf, smb_vwv13); + if ( PTR_DIFF(p, save_p) < byte_count) + p += srvstr_pull_buf(inbuf, primary_domain, p, sizeof(primary_domain), STR_TERMINATE); + else + fstrcpy( primary_domain, "null" ); + + DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", + domain, native_os, native_lanman, primary_domain)); + + if ( ra_type == RA_WIN2K ) { + if ( strlen(native_lanman) == 0 ) + ra_lanman_string( primary_domain ); + else + ra_lanman_string( native_lanman ); + } } -- cgit From 05646504c7046e61971948512d3ba6ca5eee69aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 6 Dec 2003 02:33:59 +0000 Subject: Fix for bug #445 (missing unix user on kerberos auth doesn't call add user script). Jeremy. (This used to be commit 881c5c60977d15b5d4b34fde8743deac80f11a99) --- source3/auth/auth_util.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 5d3f8f0277..6df31b94a7 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -965,7 +965,7 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, struct passwd *smb_getpwnam( char *domuser ) { - struct passwd *pw; + struct passwd *pw = NULL; char *p; fstring mapped_username; @@ -981,10 +981,20 @@ struct passwd *smb_getpwnam( char *domuser ) p += 1; fstrcpy( mapped_username, p ); map_username( mapped_username ); - return Get_Pwnam(mapped_username); + pw = Get_Pwnam(mapped_username); + if (!pw) { + /* Create local user if requested. */ + p = strchr( mapped_username, *lp_winbind_separator() ); + if (p) + p += 1; + else + p = mapped_username; + auth_add_user_script(NULL, p); + return Get_Pwnam(p); + } } - return NULL; + return pw; } /*************************************************************************** -- cgit From 570c0c12fd5c7414d9543e48bc0f9139f8371d67 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 7 Dec 2003 11:06:40 +0000 Subject: Merge from 3.0: source/libsmb/ntlmssp.c: Picked up by the build farm - despite all my efforts, security=server was broken by my NTLM2 commit. This should correctly cause the NTLM2 case not to be negotiated when 'security=server' is in effect. testsuide/build_farm/runlist: Without 'non unix accounts' we can't test security=domain on the build farm. source/rpc_server/srv_samr_nt.c: Match Win2k and return 'invalid parameter' for creating of a new account with account flags of 0. Andrew Bartlett (This used to be commit e97f1eb62ae01b5259d7ecfab9b55b07103379c7) --- source3/libsmb/ntlmssp.c | 21 +++++++++++++-------- source3/rpc_server/srv_samr_nt.c | 6 ++++++ testsuite/build_farm/runlist | 4 ++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index d361196047..ca1aa67403 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -340,7 +340,6 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { @@ -403,13 +402,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); - chal_flags = ntlmssp_state->neg_flags; - - target_name = ntlmssp_target_name(ntlmssp_state, - neg_flags, &chal_flags); - if (target_name == NULL) - return NT_STATUS_INVALID_PARAMETER; - /* Ask our caller what challenge they would like in the packet */ cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); @@ -418,6 +410,19 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } + /* The flags we send back are not just the negotiated flags, + * they are also 'what is in this packet'. Therfore, we + * operate on 'chal_flags' from here on + */ + + chal_flags = ntlmssp_state->neg_flags; + + /* get the right name to fill in as 'target' */ + target_name = ntlmssp_target_name(ntlmssp_state, + neg_flags, &chal_flags); + if (target_name == NULL) + return NT_STATUS_INVALID_PARAMETER; + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 7be9b41ee9..7f57a9fc9d 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2130,6 +2130,12 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA return nt_status; } + if (!acb_info) { + /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if + this parameter is zero (ie, no user type specified) */ + return NT_STATUS_INVALID_PARAMETER; + } + /* find the account: tell the caller if it exists. lkclXXXX i have *no* idea if this is a problem or not or even if you are supposed to construct a different diff --git a/testsuite/build_farm/runlist b/testsuite/build_farm/runlist index 5996f24ba8..594c172b6f 100644 --- a/testsuite/build_farm/runlist +++ b/testsuite/build_farm/runlist @@ -1,6 +1,6 @@ TEST_ALL="basicsmb-sharelist basicsmb-local-pass-change \ basicsmb-sharesec basicsmb-usersec \ -basicsmb-serversec basicsmb-domainsec basicsmb-domainsec-nt4 \ +basicsmb-serversec \ basicsmb-shareguest basicsmb-hostsequiv basicsmb-invalidusers \ basicsmb-hostsdeny basicsmb-remote-pass-change \ basicsmb-preexec \ @@ -15,4 +15,4 @@ torture-RW1 torture-RW2 torture-OPEN torture-XCOPY \ torture-RENAME torture-DELETE torture-PROPERTIES \ torture-MANGLE torture-FDSESS" -#basicsmb-serversec +#basicsmb-domainsec basicsmb-domainsec-nt4 \ No newline at end of file -- cgit From d1545aba66059b7a65fb46420a6048209cf33620 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 8 Dec 2003 17:42:21 +0000 Subject: make sure we use a real network address in case there are extra non-zero octets in hosts allow/deny (This used to be commit f891d434a1406d18f9842ac6b3d1ea49ee96b9bc) --- source3/lib/access.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/access.c b/source3/lib/access.c index 81eab7c738..f03f5daf33 100644 --- a/source3/lib/access.c +++ b/source3/lib/access.c @@ -43,7 +43,7 @@ static BOOL masked_match(const char *tok, const char *slash, const char *s) return (False); } - return ((addr & mask) == net); + return ((addr & mask) == (net & mask)); } /* string_match - match string against token */ -- cgit From b17feb14741c4b295b6fe2282ed764dabd0a31cd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 8 Dec 2003 17:42:26 +0000 Subject: working on bug 687; protect against null src strings in alloc_sub_basic() (This used to be commit b187511920dc6245faeb5ea6b48132bd5ba69ef9) --- source3/lib/substitute.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index ee342964d0..5dec980810 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -494,6 +494,13 @@ char *alloc_sub_basic(const char *smb_name, const char *str) struct passwd *pass; const char *local_machine_name = get_local_machine_name(); + /* workaround to prevent a crash while lookinf at bug #687 */ + + if ( !str ) { + DEBUG(0,("alloc_sub_basic: NULL source string! This should not happen\n")); + return NULL; + } + a_string = strdup(str); if (a_string == NULL) { DEBUG(0, ("alloc_sub_specified: Out of memory!\n")); -- cgit From 967fb3ec500e534d6dc54bcfe49af2cb1376bb1a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Dec 2003 02:29:24 +0000 Subject: Make intent to return only one address clear. Jeremy. (This used to be commit 08b6b1e43ce354cfb77701c8953565e1163ff76b) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 1de7413711..c7cc4848b7 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1006,9 +1006,9 @@ static BOOL internal_resolve_name(const char *name, int name_type, } } else { (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0; - *return_count = 1; } - return True; + *return_count = 1; + return True; } /* Check name cache */ -- cgit From 09c4409375289013e3c38e900cb7557d9846b955 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 9 Dec 2003 18:20:48 +0000 Subject: fix bug in get_peer_name() caused by --enable-developer and using the same src & dest strings to alpha_strcpy(); reported by Michael Young (This used to be commit 0054ce8707038444bec8c4ac8f0deea12ef65820) --- source3/lib/util_sock.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 1d62da53c5..328ca92727 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -874,6 +874,7 @@ static BOOL matchname(char *remotehost,struct in_addr addr) char *get_peer_name(int fd, BOOL force_lookup) { static pstring name_buf; + pstring tmp_name; static fstring addr_buf; struct hostent *hp; struct in_addr addr; @@ -890,10 +891,12 @@ char *get_peer_name(int fd, BOOL force_lookup) p = get_peer_addr(fd); /* it might be the same as the last one - save some DNS work */ - if (strcmp(p, addr_buf) == 0) return name_buf; + if (strcmp(p, addr_buf) == 0) + return name_buf; pstrcpy(name_buf,"UNKNOWN"); - if (fd == -1) return name_buf; + if (fd == -1) + return name_buf; fstrcpy(addr_buf, p); @@ -911,7 +914,12 @@ char *get_peer_name(int fd, BOOL force_lookup) } } - alpha_strcpy(name_buf, name_buf, "_-.", sizeof(name_buf)); + /* can't pass the same source and dest strings in when you + use --enable-developer or the clobber_region() call will + get you */ + + pstrcpy( tmp_name, name_buf ); + alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf)); if (strstr(name_buf,"..")) { pstrcpy(name_buf, "UNKNOWN"); } -- cgit From ea4e53904ed015a754b5151fdd705fbab1630750 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Dec 2003 18:34:26 +0000 Subject: Final part of fix for #445. Don't add user for machine accounts. Jeremy. (This used to be commit 0785295fe067093ea1483fc19e30c63512018db3) --- source3/auth/auth_util.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 6df31b94a7..3dc0fdbe46 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -983,6 +983,10 @@ struct passwd *smb_getpwnam( char *domuser ) map_username( mapped_username ); pw = Get_Pwnam(mapped_username); if (!pw) { + /* Don't add a machine account. */ + if (mapped_username[strlen(mapped_username)-1] == '$') + return NULL; + /* Create local user if requested. */ p = strchr( mapped_username, *lp_winbind_separator() ); if (p) -- cgit From 272be24ffd94f81c273775e154f01d93028d4b28 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 9 Dec 2003 21:31:38 +0000 Subject: working on packaging; also fixed some path issues in configure.in & Makefile.in (This used to be commit c16e51bfaf59b2d5b1b800ee272ac45b13b9a9fc) --- packaging/Fedora/filter-requires-samba.sh | 3 + packaging/Fedora/makerpms.sh.tmpl | 67 ++ packaging/Fedora/samba.log | 9 + packaging/Fedora/samba.pamd | 2 + packaging/Fedora/samba.spec.tmpl | 978 ++++++++++++++++++++++++++++++ packaging/Fedora/samba.sysconfig | 6 + packaging/Fedora/samba.xinetd | 15 + packaging/Fedora/smb.init | 117 ++++ packaging/Fedora/smbprint | 84 +++ packaging/Fedora/swat.desktop | 8 + packaging/Fedora/winbind.init | 100 +++ source3/Makefile.in | 17 +- source3/configure.in | 24 +- source3/nsswitch/winbindd_group.c | 4 +- 14 files changed, 1423 insertions(+), 11 deletions(-) create mode 100755 packaging/Fedora/filter-requires-samba.sh create mode 100644 packaging/Fedora/makerpms.sh.tmpl create mode 100644 packaging/Fedora/samba.log create mode 100644 packaging/Fedora/samba.pamd create mode 100644 packaging/Fedora/samba.spec.tmpl create mode 100644 packaging/Fedora/samba.sysconfig create mode 100644 packaging/Fedora/samba.xinetd create mode 100644 packaging/Fedora/smb.init create mode 100644 packaging/Fedora/smbprint create mode 100644 packaging/Fedora/swat.desktop create mode 100644 packaging/Fedora/winbind.init diff --git a/packaging/Fedora/filter-requires-samba.sh b/packaging/Fedora/filter-requires-samba.sh new file mode 100755 index 0000000000..1ba10a0ee3 --- /dev/null +++ b/packaging/Fedora/filter-requires-samba.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +/usr/lib/rpm/perl.req $* | grep -v "Net::LDAP" diff --git a/packaging/Fedora/makerpms.sh.tmpl b/packaging/Fedora/makerpms.sh.tmpl new file mode 100644 index 0000000000..46ef4b6353 --- /dev/null +++ b/packaging/Fedora/makerpms.sh.tmpl @@ -0,0 +1,67 @@ +#!/bin/sh +# Copyright (C) John H Terpstra 1998-2002 +# Gerald (Jerry) Carter 2003 + +# The following allows environment variables to override the target directories +# the alternative is to have a file in your home directory calles .rpmmacros +# containing the following: +# %_topdir /home/mylogin/redhat +# +# Note: Under this directory rpm expects to find the same directories that are under the +# /usr/src/redhat directory +# + +SPECDIR=`rpm --eval %_specdir` +SRCDIR=`rpm --eval %_sourcedir` + +# At this point the SPECDIR and SRCDIR vaiables must have a value! + +USERID=`id -u` +GRPID=`id -g` +VERSION='PVERSION' +SPECFILE="samba.spec" +RPMVER=`rpm --version | awk '{print $3}'` +RPM="rpmbuild" + +## +## Check the RPM version (paranoid) +## +case $RPMVER in + 4*) + echo "Supported RPM version [$RPMVER]" + ;; + *) + echo "Unknown RPM version: `rpm --version`" + exit 1 + ;; +esac + +( cd ../../source; if [ -f Makefile ]; then make distclean; fi ) +( cd ../../.. ; chown -R ${USERID}.${GRPID} samba-${VERSION} ) + +( cd ../../.. ; tar --exclude=CVS -cf - samba-${VERSION}/. | bzip2 > ${SRCDIR}/samba-${VERSION}.tar.bz2 ) + +## +## copy additional source files +## +for file in samba.pamd samba.sysconfig samba.spec \ + smb.init swat.desktop filter-requires-samba.sh \ + samba.log samba.xinetd smbprint winbind.init +do + cp -p $file ${SRCDIR} + +done + +chmod 755 ${SRCDIR}/filter-requires-samba.sh + +cp -p ${SPECFILE} ${SPECDIR} + +## +## Build +## +echo Getting Ready to build release package +cd ${SPECDIR} +${RPM} -ba --clean --rmsource $SPECFILE + +echo Done. + diff --git a/packaging/Fedora/samba.log b/packaging/Fedora/samba.log new file mode 100644 index 0000000000..04106239fb --- /dev/null +++ b/packaging/Fedora/samba.log @@ -0,0 +1,9 @@ +/var/log/samba/*.log { + notifempty + missingok + sharedscripts + copytruncate + postrotate + /bin/kill -HUP `cat /var/run/smbd.pid /var/run/nmbd.pid /var/run/winbindd.pid 2> /dev/null` 2> /dev/null || true + endscript +} diff --git a/packaging/Fedora/samba.pamd b/packaging/Fedora/samba.pamd new file mode 100644 index 0000000000..d8a27ff08f --- /dev/null +++ b/packaging/Fedora/samba.pamd @@ -0,0 +1,2 @@ +auth required /lib/security/pam_stack.so service=system-auth +account required /lib/security/pam_stack.so service=system-auth diff --git a/packaging/Fedora/samba.spec.tmpl b/packaging/Fedora/samba.spec.tmpl new file mode 100644 index 0000000000..51e68dfea2 --- /dev/null +++ b/packaging/Fedora/samba.spec.tmpl @@ -0,0 +1,978 @@ +%define initdir %{_sysconfdir}/rc.d/init.d +%define auth %(test -f /etc/pam.d/system-auth && echo /etc/pam.d/system-auth || echo) + +Summary: The Samba SMB server. +Name: samba +Version: PVERSION +Release: PRELEASE +License: GNU GPL Version 2 +Group: System Environment/Daemons +URL: http://www.samba.org/ + +Source: ftp://www.samba.org/pub/samba/%{name}-%{version}.tar.bz2 + +# Red Hat specific replacement-files +Source1: samba.log +Source2: samba.xinetd +Source3: swat.desktop +Source4: samba.sysconfig +Source5: smb.init +Source6: samba.pamd +Source7: smbprint +Source8: winbind.init + +# Don't depend on Net::LDAP +Source999: filter-requires-samba.sh + +# generic patches + +Requires: pam >= 0.64 %{auth} samba-common = %{version} +Requires: logrotate >= 3.4 initscripts >= 5.54-1 +BuildRoot: %{_tmppath}/%{name}-%{version}-root +Prereq: /sbin/chkconfig /bin/mktemp /usr/bin/killall +Prereq: fileutils sed /etc/init.d +BuildRequires: pam-devel, readline-devel, ncurses-devel, fileutils, libacl-devel, openldap-devel, krb5-devel + + +# Working around perl dependency problem from docs +%define __perl_requires %{SOURCE999} + +%description +Samba is the protocol by which a lot of PC-related machines share +files, printers, and other information (such as lists of available +files and printers). The Windows NT, OS/2, and Linux operating systems +support this natively, and add-on packages can enable the same thing +for DOS, Windows, VMS, UNIX of all kinds, MVS, and more. This package +provides an SMB server that can be used to provide network services to +SMB (sometimes called "Lan Manager") clients. Samba uses NetBIOS over +TCP/IP (NetBT) protocols and does NOT need the NetBEUI (Microsoft Raw +NetBIOS frame) protocol. + +%package client +Summary: Samba (SMB) client programs. +Group: Applications/System +Requires: samba-common = %{version} +Obsoletes: smbfs + +%description client +The samba-client package provides some SMB clients to compliment the +built-in SMB filesystem in Linux. These clients allow access of SMB +shares and printing to SMB printers. + +%package common +Summary: Files used by both Samba servers and clients. +Group: Applications/System + +%description common +Samba-common provides files necessary for both the server and client +packages of Samba. + +%package swat +Summary: The Samba SMB server configuration program. +Group: Applications/System +Requires: samba = %{version} xinetd + +%description swat +The samba-swat package includes the new SWAT (Samba Web Administration +Tool), for remotely managing Samba's smb.conf file using your favorite +Web browser. + +%prep +%setup -q + +# copy Red Hat specific scripts +cp %{SOURCE5} packaging/Fedora/ +cp %{SOURCE6} packaging/Fedora/ +cp %{SOURCE7} packaging/Fedora/ +cp %{SOURCE8} packaging/Fedora/winbind.init + +%build + +cd source +%ifarch i386 sparc +RPM_OPT_FLAGS="$RPM_OPT_FLAGS -D_FILE_OFFSET_BITS=64" +%endif +%ifarch ia64 +libtoolize --copy --force # get it to recognize IA-64 +autoheader +autoconf +EXTRA="-D_LARGEFILE64_SOURCE" +%endif + +## run autogen if missing the configure script +if [ ! -f "configure" ]; then + ./autogen.sh +fi + +CFLAGS="$RPM_OPT_FLAGS" ./configure \ + --prefix=%{_prefix} \ + --localstatedir=/var \ + --sysconfdir=/etc \ + --with-privatedir=%{_sysconfdir}/samba \ + --with-fhs \ + --with-quotas \ + --with-smbmount \ + --with-pam \ + --with-pam_smbpass \ + --with-syslog \ + --with-utmp \ + --with-sambabook=%{_datadir}/swat/using_samba \ + --with-swatdir=%{_datadir}/swat \ + --with-libsmbclient \ + --with-acl-support +make showlayout +make proto +make %{?_smp_mflags} all nsswitch/libnss_wins.so debug2html + + +%install +rm -rf $RPM_BUILD_ROOT + +mkdir -p $RPM_BUILD_ROOT/sbin +mkdir -p $RPM_BUILD_ROOT/usr/{sbin,bin} +mkdir -p $RPM_BUILD_ROOT/%{initdir} +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/{pam.d,logrotate.d} +mkdir -p $RPM_BUILD_ROOT/var/{log,spool,lib}/samba +mkdir -p $RPM_BUILD_ROOT/%{_datadir}/swat/using_samba +mkdir -p $RPM_BUILD_ROOT/%{_datadir}/samba/codepages + +cd source + +make DESTDIR=$RPM_BUILD_ROOT \ + install + +cd .. + +# Install other stuff +install -m644 packaging/RedHat/smb.conf $RPM_BUILD_ROOT%{_sysconfdir}/samba/smb.conf +install -m755 source/script/mksmbpasswd.sh $RPM_BUILD_ROOT%{_bindir} +install -m644 packaging/RedHat/smbusers $RPM_BUILD_ROOT/etc/samba/smbusers +install -m755 packaging/RedHat/smbprint $RPM_BUILD_ROOT%{_bindir} +install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT%{initdir}/smb +install -m755 packaging/RedHat/winbind.init $RPM_BUILD_ROOT%{initdir}/winbind +ln -s ../..%{initdir}/smb $RPM_BUILD_ROOT%{_sbindir}/samba +install -m644 packaging/RedHat/samba.pamd.stack $RPM_BUILD_ROOT/etc/pam.d/samba +install -m644 $RPM_SOURCE_DIR/samba.log $RPM_BUILD_ROOT/etc/logrotate.d/samba +ln -s ../usr/bin/smbmount $RPM_BUILD_ROOT/sbin/mount.smb +## mount.smbfs is installed by Samba's Makefile +## ln -s ../usr/bin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs +echo 127.0.0.1 localhost > $RPM_BUILD_ROOT%{_sysconfdir}/samba/lmhosts + +# pam_smbpass +mkdir -p $RPM_BUILD_ROOT/%{_lib}/security +mv source/bin/pam_smbpass.so $RPM_BUILD_ROOT/%{_lib}/security/pam_smbpass.so + +# winbind +mkdir -p $RPM_BUILD_ROOT/%{_lib}/security +install -m 755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/%{_lib}/security/pam_winbind.so +mkdir -p $RPM_BUILD_ROOT%{_libdir} +install -m 755 source/nsswitch/libnss_winbind.so $RPM_BUILD_ROOT/%{_lib}/libnss_winbind.so +ln -sf /%{_lib}/libnss_winbind.so $RPM_BUILD_ROOT%{_libdir}/libnss_winbind.so.2 +install -m 755 source/nsswitch/libnss_wins.so $RPM_BUILD_ROOT/%{_lib}/libnss_wins.so +ln -sf /%{_lib}/libnss_wins.so $RPM_BUILD_ROOT%{_libdir}/libnss_wins.so.2 + +# libsmbclient + +# make install puts libsmbclient.so in the wrong place on x86_64 +rm -f $RPM_BUILD_ROOT/usr/lib || true +mkdir -p $RPM_BUILD_ROOT%{_libdir} $RPM_BUILD_ROOT%{_includedir} +install -m 644 source/bin/libsmbclient.so $RPM_BUILD_ROOT%{_libdir}/libsmbclient.so +install -m 644 source/bin/libsmbclient.a $RPM_BUILD_ROOT%{_libdir}/libsmbclient.a +install -m 644 source/include/libsmbclient.h $RPM_BUILD_ROOT%{_includedir} + +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d +install -m644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d/swat + +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig +install -m644 %{SOURCE4} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/samba + +## +## Clean out man pages for tools not installed here +## +rm -f $RPM_BUILD_ROOT/%{_mandir}/man1/editreg.1* +rm -f $RPM_BUILD_ROOT%{_mandir}/man1/log2pcap.1* +rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbsh.1* +rm -f $RPM_BUILD_ROOT/%{_mandir}/man8/mount.cifs.8* + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +/sbin/chkconfig --add smb + +%preun +if [ $1 = 0 ] ; then + /sbin/chkconfig --del smb + rm -rf /var/log/samba/* /var/cache/samba/* + /sbin/service smb stop >/dev/null 2>&1 +fi +exit 0 + +%postun +if [ "$1" -ge "1" ]; then + %{initdir}/smb condrestart >/dev/null 2>&1 +fi + +%post common +/sbin/chkconfig --add winbind +/sbin/ldconfig + +%preun common +if [ $1 = 0 ] ; then + /sbin/chkconfig --del winbind + /sbin/service winbind stop >/dev/null 2>&1 +fi +exit 0 + +%postun common -p /sbin/ldconfig + +%triggerpostun -- samba < 1.9.18p7 +if [ $1 != 0 ]; then + /sbin/chkconfig --add smb +fi + +%triggerpostun -- samba < 2.0.5a-3 +if [ $1 != 0 ]; then + [ ! -d /var/lock/samba ] && mkdir -m 0755 /var/lock/samba + [ ! -d /var/spool/samba ] && mkdir -m 1777 /var/spool/samba + chmod 644 /etc/services + [ -f /etc/inetd.conf ] && chmod 644 /etc/inetd.conf +fi + +%files +%defattr(-,root,root) +%doc README COPYING Manifest +%doc WHATSNEW.txt Roadmap +%doc docs +%doc examples/autofs examples/LDAP examples/libsmbclient examples/misc examples/printer-accounting +%doc examples/printing + +%attr(755,root,root) /%{_lib}/security/pam_smbpass.so +%{_sbindir}/smbd +%{_sbindir}/nmbd +# %{_bindir}/make_unicodemap +%{_bindir}/mksmbpasswd.sh +%{_bindir}/smbcontrol +%{_bindir}/smbstatus +# %{_bindir}/smbadduser +%{_bindir}/tdbbackup +%config(noreplace) %{_sysconfdir}/sysconfig/samba +%config(noreplace) %{_sysconfdir}/samba/smbusers +%attr(755,root,root) %config %{initdir}/smb +%config(noreplace) %{_sysconfdir}/logrotate.d/samba +%config(noreplace) %{_sysconfdir}/pam.d/samba +# %{_mandir}/man1/make_unicodemap.1* +%{_mandir}/man1/smbcontrol.1* +%{_mandir}/man1/smbstatus.1* +%{_mandir}/man5/smbpasswd.5* +%{_mandir}/man7/samba.7* +%{_mandir}/man7/Samba.7* +%{_mandir}/man8/nmbd.8* +%{_mandir}/man8/pdbedit.8* +%{_mandir}/man8/smbd.8* +%{_mandir}/man8/tdbbackup.8* +#%{_mandir}/ja/man1/smbstatus.1* +#%{_mandir}/ja/man5/smbpasswd.5* +#%{_mandir}/ja/man7/samba.7* +#%{_mandir}/ja/man8/smbd.8* +#%{_mandir}/ja/man8/nmbd.8* +%{_libdir}/samba/vfs + +%attr(0700,root,root) %dir /var/log/samba +%attr(1777,root,root) %dir /var/spool/samba + +%files swat +%defattr(-,root,root) +%config(noreplace) %{_sysconfdir}/xinetd.d/swat +%{_datadir}/swat +%{_sbindir}/swat +%{_mandir}/man8/swat.8* +#%{_mandir}/ja/man8/swat.8* +%attr(755,root,root) %{_libdir}/samba/*.msg + +%files client +%defattr(-,root,root) +/sbin/mount.smb +/sbin/mount.smbfs +%{_libdir}/samba/lowcase.dat +%{_libdir}/samba/upcase.dat +%{_libdir}/samba/valid.dat +%{_bindir}/rpcclient +%{_bindir}/smbcacls +%{_bindir}/smbmount +%{_bindir}/smbmnt +%{_bindir}/smbumount +%{_bindir}/findsmb +%{_mandir}/man8/smbmnt.8* +%{_mandir}/man8/smbmount.8* +%{_mandir}/man8/smbumount.8* +%{_mandir}/man8/smbspool.8* +%{_bindir}/nmblookup +%{_bindir}/smbclient +%{_bindir}/smbprint +%{_bindir}/smbspool +%{_bindir}/smbtar +%{_bindir}/net +%{_bindir}/smbtree +%{_mandir}/man1/findsmb.1* +%{_mandir}/man1/nmblookup.1* +%{_mandir}/man1/rpcclient.1* +%{_mandir}/man1/smbcacls.1* +%{_mandir}/man1/smbclient.1* +%{_mandir}/man1/smbtar.1* +%{_mandir}/man1/smbtree.1* +%{_mandir}/man8/net.8* +#%{_mandir}/ja/man1/smbtar.1* +#%{_mandir}/ja/man1/smbclient.1* +#%{_mandir}/ja/man1/nmblookup.1* + +%files common +%defattr(-,root,root) +/%{_lib}/libnss_wins.so.* +/%{_lib}/libnss_winbind.so.* +/%{_lib}/security/pam_winbind.so +%{_libdir}/libsmbclient.a +%{_libdir}/libsmbclient.so +%{_libdir}/samba/charset/CP*.so +%{_includedir}/libsmbclient.h +%{_bindir}/testparm +%{_bindir}/testprns +%{_bindir}/smbpasswd +# %{_bindir}/make_printerdef +%{_bindir}/wbinfo +# %{_bindir}/editreg +%{_bindir}/ntlm_auth +%{_bindir}/pdbedit +%{_bindir}/profiles +%{_bindir}/smbcquotas +#%{_bindir}/vfstest +%{_sbindir}/winbindd +%dir /var/cache/samba +%attr(750,root,root) %dir /var/cache/samba/winbindd_privileged +%config(noreplace) %{_sysconfdir}/samba/smb.conf +%config(noreplace) %{_sysconfdir}/samba/lmhosts +%dir %{_datadir}/samba +%dir %{_datadir}/samba/codepages +%dir %{_sysconfdir}/samba +%{initdir}/winbind +# %{_datadir}/samba/codepages/* +# %{_mandir}/man1/make_smbcodepage.1* +%{_mandir}/man1/ntlm_auth.1* +%{_mandir}/man1/profiles.1* +%{_mandir}/man1/smbcquotas.1* +%{_mandir}/man1/testparm.1* +%{_mandir}/man1/testprns.1* +%{_mandir}/man5/smb.conf.5* +%{_mandir}/man5/lmhosts.5* +%{_mandir}/man8/smbpasswd.8* +%{_mandir}/man1/wbinfo.1* +%{_mandir}/man8/winbindd.8* +%{_mandir}/man1/vfstest.1* + +# #%lang(ja) %{_mandir}/ja/man1/make_smbcodepage.1* +#%lang(ja) %{_mandir}/ja/man1/testparm.1* +#%lang(ja) %{_mandir}/ja/man1/testprns.1* +#%lang(ja) %{_mandir}/ja/man5/smb.conf.5* +#%lang(ja) %{_mandir}/ja/man5/lmhosts.5* +#%lang(ja) %{_mandir}/ja/man8/smbpasswd.8* + +%changelog +* Thu Sep 25 2003 Jay Fenlason 3.0.0-15 +- New 3.0.0 final release +- merge nmbd-netbiosname and testparm patches from 3E branch +- updated the -logfiles patch to work against 3.0.0 +- updated the pie patch +- update the VERSION file during build +- use make -j if avaliable +- merge the winbindd_privileged change from 3E +- merge the "rm /usr/lib" patch that allows Samba to build on 64-bit + platforms despite the broken Makefile + +* Mon Aug 18 2003 Jay Fenlason +- Merge from samba-3E-branch after samba-3.0.0rc1 was released + +* Wed Jul 23 2003 Jay Fenlason 3.0.0-3beta3 +- Merge from 3.0.0-2beta3.3E +- (Correct log file names (#100981).) +- (Fix pidfile directory in samab.log) +- (Remove obsolete samba-3.0.0beta2.tar.bz2.md5 file) +- (Move libsmbclient to the -common package (#99449)) + +* Tue Jun 22 2003 Nalin Dahyabhai 2.2.8a-4 +- rebuild + +* Wed Jun 04 2003 Elliot Lee +- rebuilt + +* Wed May 28 2003 Jay Fenlason 2.2.8a-2 +- add libsmbclient.so for gnome-vfs-extras +- Edit specfile to specify /var/run for pid files +- Move /tmp/.winbindd/socket to /var/run/winbindd/socket + +* Wed May 14 2003 Florian La Roche +- add proper ldconfig calls + +* Thu Apr 24 2003 Jay Fenlason 2.2.8a-1 +- upgrade to 2.2.8a +- remove old .md5 files +- add "pid directory = /var/run" to the smb.conf file. Fixes #88495 +- Patch from jra@dp.samba.org to fix a delete-on-close regression + +* Mon Mar 24 2003 Jay Fenlason 2.2.8-0 +- Upgrade to 2.2.8 +- removed commented out patches. +- removed old patches and .md5 files from the repository. +- remove duplicate /sbin/chkconfig --del winbind which causes + warnings when removing samba. +- Fixed minor bug in smbprint that causes it to fail when called with + more than 10 parameters: the accounting file (and spool directory + derived from it) were being set wrong due to missing {}. This closes + bug #86473. +- updated smb.conf patch, includes new defaults to close bug #84822. + +* Mon Feb 24 2003 Elliot Lee +- rebuilt + +* Thu Feb 20 2003 Jonathan Blandford 2.2.7a-5 +- remove swat.desktop file + +* Thu Feb 20 2003 Nalin Dahyabhai 2.2.7a-4 +- relink libnss_wins.so with SHLD="%{__cc} -lnsl" to force libnss_wins.so to + link with libnsl, avoiding unresolved symbol errors on functions in libnsl + +* Mon Feb 10 2003 Jay Fenlason 2.2.7a-3 +- edited spec file to put .so files in the correct directories + on 64-bit platforms that have 32-bit compatability issues + (sparc64, x86_64, etc). This fixes bugzilla #83782. +- Added samba-2.2.7a-error.patch from twaugh. This fixes + bugzilla #82454. + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Thu Jan 9 2003 Jay Fenlason 2.2.7a-1 +- Update to 2.2.7a +- Change default printing system to CUPS +- Turn on pam_smbpass +- Turn on msdfs + +* Sat Jan 4 2003 Jeff Johnson 2.2.7-5 +- use internal dep generator. + +* Sat Dec 14 2002 Tim Powers 2.2.7-4 +- don't use rpms internal dep generator + +* Mon Dec 02 2002 Elliot Lee 2.2.7-3 +- Fix missing doc files. +- Fix multilib issues + +* Wed Nov 20 2002 Bill Nottingham 2.2.7-2 +- update to 2.2.7 +- add patch for LFS in smbclient () + +* Wed Aug 28 2002 Trond Eivind Glomsrød 2.2.5-10 +- logrotate fixes (#65007) + +* Mon Aug 26 2002 Trond Eivind Glomsrød 2.2.5-9 +- /usr/lib was used in place of %%{_libdir} in three locations (#72554) + +* Mon Aug 5 2002 Trond Eivind Glomsrød 2.2.5-8 +- Initscript fix (#70720) + +* Fri Jul 26 2002 Trond Eivind Glomsrød 2.2.5-7 +- Enable VFS support and compile the "recycling" module (#69796) +- more selective includes of the examples dir + +* Tue Jul 23 2002 Trond Eivind Glomsrød 2.2.5-6 +- Fix the lpq parser for better handling of LPRng systems (#69352) + +* Tue Jul 23 2002 Trond Eivind Glomsrød 2.2.5-5 +- desktop file fixes (#69505) + +* Wed Jun 26 2002 Trond Eivind Glomsrød 2.2.5-4 +- Enable ACLs + +* Tue Jun 25 2002 Trond Eivind Glomsrød 2.2.5-3 +- Make it not depend on Net::LDAP - those are doc files and examples + +* Fri Jun 21 2002 Tim Powers +- automated rebuild + +* Thu Jun 20 2002 Trond Eivind Glomsrød 2.2.5-1 +- 2.2.5 + +* Fri Jun 14 2002 Trond Eivind Glomsrød 2.2.4-5 +- Move the post/preun of winbind into the -common subpackage, + where the script is (#66128) + +* Tue Jun 4 2002 Trond Eivind Glomsrød 2.2.4-4 +- Fix pidfile locations so it runs properly again (2.2.4 + added a new directtive - #65007) + +* Thu May 23 2002 Tim Powers +- automated rebuild + +* Tue May 14 2002 Trond Eivind Glomsrød 2.2.4-2 +- Fix #64804 + +* Thu May 9 2002 Trond Eivind Glomsrød 2.2.4-1 +- 2.2.4 +- Removed some zero-length and CVS internal files +- Make it build + +* Wed Apr 10 2002 Trond Eivind Glomsrød 2.2.3a-6 +- Don't use /etc/samba.d in smbadduser, it should be /etc/samba + +* Thu Apr 4 2002 Trond Eivind Glomsrød 2.2.3a-5 +- Add libsmbclient.a w/headerfile for KDE (#62202) + +* Tue Mar 26 2002 Trond Eivind Glomsrød 2.2.3a-4 +- Make the logrotate script look the correct place for the pid files + +* Thu Mar 14 2002 Nalin Dahyabhai 2.2.3a-3 +- include interfaces.o in pam_smbpass.so, which needs symbols from interfaces.o + (patch posted to samba-list by Ilia Chipitsine) + +* Thu Feb 21 2002 Trond Eivind Glomsrød 2.2.3a-2 +- Rebuild + +* Thu Feb 7 2002 Trond Eivind Glomsrød 2.2.3a-1 +- 2.2.3a + +* Mon Feb 4 2002 Trond Eivind Glomsrød 2.2.3-1 +- 2.2.3 + +* Thu Nov 29 2001 Trond Eivind Glomsrød 2.2.2-8 +- New pam configuration file for samba + +* Tue Nov 27 2001 Trond Eivind Glomsrød 2.2.2-7 +- Enable PAM session controll and password sync + +* Tue Nov 13 2001 Trond Eivind Glomsrød 2.2.2-6 +- Move winbind files to samba-common. Add separate initscript for + winbind +- Fixes for winbind - protect global variables with mutex, use + more secure getenv + +* Thu Nov 8 2001 Trond Eivind Glomsrød 2.2.2-5 +- Teach smbadduser about "getent passwd" +- Fix more pid-file references +- Add (conditional) winbindd startup to the initscript, configured in + /etc/sysconfig/samba + +* Wed Nov 7 2001 Trond Eivind Glomsrød 2.2.2-4 +- Fix pid-file reference in logrotate script +- include pam and nss modules for winbind + +* Mon Nov 5 2001 Trond Eivind Glomsrød 2.2.2-3 +- Add "--with-utmp" to configure options (#55372) +- Include winbind, pam_smbpass.so, rpcclient and smbcacls +- start using /var/cache/samba, we need to keep state and there is + more than just locks involved + +* Sat Nov 03 2001 Florian La Roche 2.2.2-2 +- add "reload" to the usage string in the startup script + +* Mon Oct 15 2001 Trond Eivind Glomsrød 2.2.2-1 +- 2.2.2 + +* Tue Sep 18 2001 Trond Eivind Glomsrød 2.2.1a-5 +- Add patch from Jeremy Allison to fix IA64 alignment problems (#51497) + +* Mon Aug 13 2001 Trond Eivind Glomsrød +- Don't include smbpasswd in samba, it's in samba-common (#51598) +- Add a disabled "obey pam restrictions" statement - it's not + active, as we use encrypted passwords, but if the admin turns + encrypted passwords off the choice is available. (#31351) + +* Wed Aug 8 2001 Trond Eivind Glomsrød +- Use /var/cache/samba instead of /var/lock/samba +- Remove "domain controller" keyword from smb.conf, it's + deprecated (from #13704) +- Sync some examples with smb.conf.default +- Fix password synchronization (#16987) + +* Fri Jul 20 2001 Trond Eivind Glomsrød +- Tweaks of BuildRequires (#49581) + +* Wed Jul 11 2001 Trond Eivind Glomsrød +- 2.2.1a bugfix release + +* Tue Jul 10 2001 Trond Eivind Glomsrød +- 2.2.1, which should work better for XP + +* Sat Jun 23 2001 Trond Eivind Glomsrød +- 2.2.0a security fix +- Mark lograte and pam configuration files as noreplace + +* Fri Jun 22 2001 Trond Eivind Glomsrød +- Add the /etc/samba directory to samba-common + +* Thu Jun 21 2001 Trond Eivind Glomsrød +- Add improvements to the smb.conf as suggested in #16931 + +* Tue Jun 19 2001 Trond Eivind Glomsrød + (these changes are from the non-head version) +- Don't include /usr/sbin/samba, it's the same as the initscript +- unset TMPDIR, as samba can't write into a TMPDIR owned + by root (#41193) +- Add pidfile: lines for smbd and nmbd and a config: line + in the initscript (#15343) +- don't use make -j +- explicitly include /usr/share/samba, not just the files in it + +* Tue Jun 19 2001 Bill Nottingham +- mount.smb/mount.smbfs go in /sbin, *not* %%{_sbindir} + +* Fri Jun 8 2001 Preston Brown +- enable encypted passwords by default + +* Thu Jun 7 2001 Helge Deller +- build as 2.2.0-1 release +- skip the documentation-directories docbook, manpages and yodldocs +- don't include *.sgml documentation in package +- moved codepage-directory to /usr/share/samba/codepages +- make it compile with glibc-2.2.3-10 and kernel-headers-2.4.2-2 + +* Mon May 21 2001 Helge Deller +- updated to samba 2.2.0 +- moved codepages to %{_datadir}/samba/codepages +- use all available CPUs for building rpm packages +- use %{_xxx} defines at most places in spec-file +- "License:" replaces "Copyright:" +- dropped excludearch sparc +- de-activated japanese patches 100 and 200 for now + (they need to be fixed and tested wth 2.2.0) +- separated swat.desktop file from spec-file and added + german translations +- moved /etc/sysconfig/samba to a separate source-file +- use htmlview instead of direct call to netscape in + swat.desktop-file + +* Mon May 7 2001 Bill Nottingham +- device-remove security fix again () + +* Fri Apr 20 2001 Bill Nottingham +- fix tempfile security problems, officially () +- update to 2.0.8 + +* Sun Apr 8 2001 Bill Nottingham +- turn of SSL, kerberos + +* Thu Apr 5 2001 Bill Nottingham +- fix tempfile security problems (patch from ) + +* Thu Mar 29 2001 Bill Nottingham +- fix quota support, and quotas with the 2.4 kernel (#31362, #33915) + +* Mon Mar 26 2001 Nalin Dahyabhai +- tweak the PAM code some more to try to do a setcred() after initgroups() +- pull in all of the optflags on i386 and sparc +- don't explicitly enable Kerberos support -- it's only used for password + checking, and if PAM is enabled it's a no-op anyway + +* Mon Mar 5 2001 Tim Waugh +- exit successfully from preun script (bug #30644). + +* Fri Mar 2 2001 Nalin Dahyabhai +- rebuild in new environment + +* Wed Feb 14 2001 Bill Nottingham +- updated japanese stuff (#27683) + +* Fri Feb 9 2001 Bill Nottingham +- fix trigger (#26859) + +* Wed Feb 7 2001 Bill Nottingham +- add i18n support, japanese patch (#26253) + +* Wed Feb 7 2001 Trond Eivind Glomsrød +- i18n improvements in initscript (#26537) + +* Wed Jan 31 2001 Bill Nottingham +- put smbpasswd in samba-common (#25429) + +* Wed Jan 24 2001 Bill Nottingham +- new i18n stuff + +* Sun Jan 21 2001 Bill Nottingham +- rebuild + +* Thu Jan 18 2001 Bill Nottingham +- i18n-ize initscript +- add a sysconfig file for daemon options (#23550) +- clarify smbpasswd man page (#23370) +- build with LFS support (#22388) +- avoid extraneous pam error messages (#10666) +- add Urban Widmark's bug fixes for smbmount (#19623) +- fix setgid directory modes (#11911) +- split swat into subpackage (#19706) + +* Wed Oct 25 2000 Nalin Dahyabhai +- set a default CA certificate path in smb.conf (#19010) +- require openssl >= 0.9.5a-20 to make sure we have a ca-bundle.crt file + +* Mon Oct 16 2000 Bill Nottingham +- fix swat only_from line (#18726, others) +- fix attempt to write outside buildroot on install (#17943) + +* Mon Aug 14 2000 Bill Nottingham +- add smbspool back in (#15827) +- fix absolute symlinks (#16125) + +* Sun Aug 6 2000 Philipp Knirsch +- bugfix for smbadduser script (#15148) + +* Mon Jul 31 2000 Matt Wilson +- patch configure.ing (patch11) to disable cups test +- turn off swat by default + +* Fri Jul 28 2000 Bill Nottingham +- fix condrestart stuff + +* Fri Jul 21 2000 Bill Nottingham +- add copytruncate to logrotate file (#14360) +- fix init script (#13708) + +* Sat Jul 15 2000 Bill Nottingham +- move initscript back +- remove 'Using Samba' book from %%doc +- move stuff to /etc/samba (#13708) +- default configuration tweaks (#13704) +- some logrotate tweaks + +* Wed Jul 12 2000 Prospector +- automatic rebuild + +* Tue Jul 11 2000 Bill Nottingham +- fix logrotate script (#13698) + +* Thu Jul 6 2000 Bill Nottingham +- fix initscripts req (prereq /etc/init.d) + +* Wed Jul 5 2000 Than Ngo +- add initdir macro to handle the initscript directory +- add a new macro to handle /etc/pam.d/system-auth + +* Thu Jun 29 2000 Nalin Dahyabhai +- enable Kerberos 5 and SSL support +- patch for duplicate profile.h headers + +* Thu Jun 29 2000 Bill Nottingham +- fix init script + +* Tue Jun 27 2000 Bill Nottingham +- rename samba logs (#11606) + +* Mon Jun 26 2000 Bill Nottingham +- initscript munging + +* Fri Jun 16 2000 Bill Nottingham +- configure the swat stuff usefully +- re-integrate some specfile tweaks that got lost somewhere + +* Thu Jun 15 2000 Bill Nottingham +- rebuild to get rid of cups dependency + +* Wed Jun 14 2000 Nalin Dahyabhai +- tweak logrotate configurations to use the PID file in /var/lock/samba + +* Sun Jun 11 2000 Bill Nottingham +- rebuild in new environment + +* Thu Jun 1 2000 Nalin Dahyabhai +- change PAM setup to use system-auth + +* Mon May 8 2000 Bill Nottingham +- fixes for ia64 + +* Sat May 6 2000 Bill Nottingham +- switch to %%configure + +* Wed Apr 26 2000 Nils Philippsen +- version 2.0.7 + +* Sun Mar 26 2000 Florian La Roche +- simplify preun + +* Thu Mar 16 2000 Bill Nottingham +- fix yp_get_default_domain in autoconf +- only link against readline for smbclient +- fix log rotation (#9909) + +* Fri Feb 25 2000 Bill Nottingham +- fix trigger, again. + +* Mon Feb 7 2000 Bill Nottingham +- fix trigger. + +* Fri Feb 4 2000 Bill Nottingham +- turn on quota support + +* Mon Jan 31 2000 Cristian Gafton +- rebuild to fox dependencies +- man pages are compressed + +* Fri Jan 21 2000 Bill Nottingham +- munge post scripts slightly + +* Wed Jan 19 2000 Bill Nottingham +- turn on mmap again. Wheee. +- ship smbmount on alpha + +* Mon Dec 6 1999 Bill Nottingham +- turn off mmap. ;) + +* Wed Dec 1 1999 Bill Nottingham +- change /var/log/samba to 0700 +- turn on mmap support + +* Thu Nov 11 1999 Bill Nottingham +- update to 2.0.6 + +* Fri Oct 29 1999 Bill Nottingham +- add a %defattr for -common + +* Tue Oct 5 1999 Bill Nottingham +- shift some files into -client +- remove /home/samba from package. + +* Tue Sep 28 1999 Bill Nottingham +- initscript oopsie. killproc -HUP, not other way around. + +* Sat Sep 26 1999 Bill Nottingham +- script cleanups. Again. + +* Wed Sep 22 1999 Bill Nottingham +- add a patch to fix dropped reconnection attempts + +* Mon Sep 6 1999 Jeff Johnson +- use cp rather than mv to preserve /etc/services perms (#4938 et al). +- use mktemp to generate /etc/tmp.XXXXXX file name. +- add prereqs on sed/mktemp/killall (need to move killall to /bin). +- fix trigger syntax (i.e. "samba < 1.9.18p7" not "samba < samba-1.9.18p7") + +* Mon Aug 30 1999 Bill Nottingham +- sed "s|nawk|gawk|" /usr/bin/convert_smbpasswd + +* Sat Aug 21 1999 Bill Nottingham +- fix typo in mount.smb + +* Fri Aug 20 1999 Bill Nottingham +- add a %trigger to work around (sort of) broken scripts in + previous releases + +* Mon Aug 16 1999 Bill Nottingham +- initscript munging + +* Mon Aug 9 1999 Bill Nottingham +- add domain parsing to mount.smb + +* Fri Aug 6 1999 Bill Nottingham +- add a -common package, shuffle files around. + +* Fri Jul 23 1999 Bill Nottingham +- add a chmod in %postun so /etc/services & inetd.conf don't become unreadable + +* Wed Jul 21 1999 Bill Nottingham +- update to 2.0.5 +- fix mount.smb - smbmount options changed again......... +- fix postun. oops. +- update some stuff from the samba team's spec file. + +* Fri Jun 18 1999 Bill Nottingham +- split off clients into separate package +- don't run samba by default + +* Mon Jun 14 1999 Bill Nottingham +- fix one problem with mount.smb script +- fix smbpasswd on sparc with a really ugly kludge + +* Thu Jun 10 1999 Dale Lovelace +- fixed logrotate script + +* Tue May 25 1999 Bill Nottingham +- turn of 64-bit locking on 32-bit platforms + +* Thu May 20 1999 Bill Nottingham +- so many releases, so little time +- explicitly uncomment 'printing = bsd' in sample config + +* Tue May 18 1999 Bill Nottingham +- update to 2.0.4a +- fix mount.smb arg ordering + +* Fri Apr 16 1999 Bill Nottingham +- go back to stop/start for restart (-HUP didn't work in testing) + +* Fri Mar 26 1999 Bill Nottingham +- add a mount.smb to make smb mounting a little easier. +- smb filesystems apparently don't work on alpha. Oops. + +* Thu Mar 25 1999 Bill Nottingham +- always create codepages + +* Tue Mar 23 1999 Bill Nottingham +- logrotate changes + +* Sun Mar 21 1999 Cristian Gafton +- auto rebuild in the new build environment (release 3) + +* Fri Mar 19 1999 Preston Brown +- updated init script to use graceful restart (not stop/start) + +* Tue Mar 9 1999 Bill Nottingham +- update to 2.0.3 + +* Thu Feb 18 1999 Bill Nottingham +- update to 2.0.2 + +* Mon Feb 15 1999 Bill Nottingham +- swat swat + +* Tue Feb 9 1999 Bill Nottingham +- fix bash2 breakage in post script + +* Fri Feb 5 1999 Bill Nottingham +- update to 2.0.0 + +* Mon Oct 12 1998 Cristian Gafton +- make sure all binaries are stripped + +* Thu Sep 17 1998 Jeff Johnson +- update to 1.9.18p10. +- fix %triggerpostun. + +* Tue Jul 07 1998 Erik Troan +- updated postun triggerscript to check $0 +- clear /etc/codepages from %preun instead of %postun + +* Mon Jun 08 1998 Erik Troan +- made the %postun script a tad less agressive; no reason to remove + the logs or lock file (after all, if the lock file is still there, + samba is still running) +- the %postun and %preun should only exectute if this is the final + removal +- migrated %triggerpostun from Red Hat's samba package to work around + packaging problems in some Red Hat samba releases + +* Sun Apr 26 1998 John H Terpstra +- minor tidy up in preparation for release of 1.9.18p5 +- added findsmb utility from SGI package + +* Wed Mar 18 1998 John H Terpstra +- Updated version and codepage info. +- Release to test name resolve order + +* Sat Jan 24 1998 John H Terpstra +- Many optimisations (some suggested by Manoj Kasichainula +- Use of chkconfig in place of individual symlinks to /etc/rc.d/init/smb +- Compounded make line +- Updated smb.init restart mechanism +- Use compound mkdir -p line instead of individual calls to mkdir +- Fixed smb.conf file path for log files +- Fixed smb.conf file path for incoming smb print spool directory +- Added a number of options to smb.conf file +- Added smbadduser command (missed from all previous RPMs) - Doooh! +- Added smbuser file and smb.conf file updates for username map + diff --git a/packaging/Fedora/samba.sysconfig b/packaging/Fedora/samba.sysconfig new file mode 100644 index 0000000000..944b72fcc2 --- /dev/null +++ b/packaging/Fedora/samba.sysconfig @@ -0,0 +1,6 @@ +# Options to smbd +SMBDOPTIONS="-D" +# Options to nmbd +NMBDOPTIONS="-D" +# Options for winbindd +WINBINDOPTIONS="" diff --git a/packaging/Fedora/samba.xinetd b/packaging/Fedora/samba.xinetd new file mode 100644 index 0000000000..8b62348dde --- /dev/null +++ b/packaging/Fedora/samba.xinetd @@ -0,0 +1,15 @@ +# default: off +# description: SWAT is the Samba Web Admin Tool. Use swat \ +# to configure your Samba server. To use SWAT, \ +# connect to port 901 with your favorite web browser. +service swat +{ + port = 901 + socket_type = stream + wait = no + only_from = 127.0.0.1 + user = root + server = /usr/sbin/swat + log_on_failure += USERID + disable = yes +} diff --git a/packaging/Fedora/smb.init b/packaging/Fedora/smb.init new file mode 100644 index 0000000000..fca823a064 --- /dev/null +++ b/packaging/Fedora/smb.init @@ -0,0 +1,117 @@ +#!/bin/sh +# +# chkconfig: - 91 35 +# description: Starts and stops the Samba smbd and nmbd daemons \ +# used to provide SMB network services. +# +# pidfile: /var/run/samba/smbd.pid +# pidfile: /var/run/samba/nmbd.pid +# config: /etc/samba/smb.conf + + +# Source function library. +if [ -f /etc/init.d/functions ] ; then + . /etc/init.d/functions +elif [ -f /etc/rc.d/init.d/functions ] ; then + . /etc/rc.d/init.d/functions +else + exit 0 +fi + +# Avoid using root's TMPDIR +unset TMPDIR + +# Source networking configuration. +. /etc/sysconfig/network + +if [ -f /etc/sysconfig/samba ]; then + . /etc/sysconfig/samba +fi + +# Check that networking is up. +[ ${NETWORKING} = "no" ] && exit 0 + +# Check that smb.conf exists. +[ -f /etc/samba/smb.conf ] || exit 0 + +# Check that we can write to it... so non-root users stop here +[ -w /etc/samba/smb.conf ] || exit 0 + + +RETVAL=0 + + +start() { + KIND="SMB" + echo -n $"Starting $KIND services: " + daemon smbd $SMBDOPTIONS + RETVAL=$? + echo + KIND="NMB" + echo -n $"Starting $KIND services: " + daemon nmbd $NMBDOPTIONS + RETVAL2=$? + echo + [ $RETVAL -eq 0 -a $RETVAL2 -eq 0 ] && touch /var/lock/subsys/smb || \ + RETVAL=1 + return $RETVAL +} + +stop() { + KIND="SMB" + echo -n $"Shutting down $KIND services: " + killproc smbd + RETVAL=$? + echo + KIND="NMB" + echo -n $"Shutting down $KIND services: " + killproc nmbd + RETVAL2=$? + [ $RETVAL -eq 0 -a $RETVAL2 -eq 0 ] && rm -f /var/lock/subsys/smb + echo "" + return $RETVAL +} + +restart() { + stop + start +} + +reload() { + echo -n $"Reloading smb.conf file: " + killproc smbd -HUP + RETVAL=$? + echo + return $RETVAL +} + +rhstatus() { + status smbd + status nmbd +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + reload) + reload + ;; + status) + rhstatus + ;; + condrestart) + [ -f /var/lock/subsys/smb ] && restart || : + ;; + *) + echo $"Usage: $0 {start|stop|restart|reload|status|condrestart}" + exit 1 +esac + +exit $? diff --git a/packaging/Fedora/smbprint b/packaging/Fedora/smbprint new file mode 100644 index 0000000000..1c3959d49b --- /dev/null +++ b/packaging/Fedora/smbprint @@ -0,0 +1,84 @@ +#!/bin/sh +# This script is an input filter for printcap printing on a unix machine. It +# uses the smbclient program to print the file to the specified smb-based +# server and service. +# For example you could have a printcap entry like this +# +# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint +# +# which would create a unix printer called "smb" that will print via this +# script. You will need to create the spool directory /usr/spool/smb with +# appropriate permissions and ownerships for your system. + +# Set these to the server and service you wish to print to +# In this example I have a WfWg PC called "lapland" that has a printer +# exported called "printer" with no password. + +# +# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton) +# so that the server, service, and password can be read from +# a /usr/var/spool/lpd/PRINTNAME/.config file. +# +# In order for this to work the /etc/printcap entry must include an +# accounting file (af=...): +# +# cdcolour:\ +# :cm=CD IBM Colorjet on 6th:\ +# :sd=/var/spool/lpd/cdcolour:\ +# :af=/var/spool/lpd/cdcolour/acct:\ +# :if=/usr/local/etc/smbprint:\ +# :mx=0:\ +# :lp=/dev/null: +# +# The /usr/var/spool/lpd/PRINTNAME/.config file should contain: +# share=PC_SERVER +# user="user" +# password="password" +# +# Please, do not modify the order in the file. +# Example: +# share=\\server\deskjet +# user="fred" +# password="" + +# +# The last parameter to the filter is the accounting file name. +# Extract the directory name from the file name. +# Concat this with /.config to get the config file. +# +eval acct_file=\${$#} +spool_dir=`dirname $acct_file` +config_file=$spool_dir/.config + +# Should read the following variables set in the config file: +# share +# hostip +# user +# password + +eval `cat $config_file` + +share=`echo $share | sed "s/[\]/\//g"` + +if [ "$user" != "" ]; then + usercmd="-U" +else + usercmd="" +fi + +if [ "$workgroup" != "" ]; then + workgroupcmd="-W" +else + workgroupcmd="" +fi + +if [ "$translate" = "yes" ]; then + command="translate ; print -" +else + command="print -" +fi +#echo $share $password $translate $x_command > /tmp/smbprint.log + +cat | /usr/bin/smbclient "$share" "$password" -E ${hostip:+-I} \ + $hostip -N -P $usercmd "$user" $workgroupcmd "$workgroup" \ + -c "$command" 2>/dev/null diff --git a/packaging/Fedora/swat.desktop b/packaging/Fedora/swat.desktop new file mode 100644 index 0000000000..0d7b4b5c48 --- /dev/null +++ b/packaging/Fedora/swat.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=Samba Configuration +Name[de]=Samba Konfiguration +Type=Application +Comment=Configure Samba with a web based interface +Exec=htmlview http://127.0.0.1:901/ +Terminal=false +Categories=X-Red-Hat-Extra;Application;System;X-Red-Hat-ServerConfig; diff --git a/packaging/Fedora/winbind.init b/packaging/Fedora/winbind.init new file mode 100644 index 0000000000..ced81135b2 --- /dev/null +++ b/packaging/Fedora/winbind.init @@ -0,0 +1,100 @@ +#!/bin/sh +# +# chkconfig: - 91 35 +# description: Starts and stops the Samba winbind daemon +# # +# pidfile: /var/cache/samba/winbind.pid +# config: /etc/samba/smb.conf + + +# Source function library. +if [ -f /etc/init.d/functions ] ; then + . /etc/init.d/functions +elif [ -f /etc/rc.d/init.d/functions ] ; then + . /etc/rc.d/init.d/functions +else + exit 0 +fi + +# Avoid using root's TMPDIR +unset TMPDIR + +# Source networking configuration. +. /etc/sysconfig/network + +if [ -f /etc/sysconfig/samba ]; then + . /etc/sysconfig/samba +fi + +# Check that networking is up. +[ ${NETWORKING} = "no" ] && exit 0 + +# Check that smb.conf exists. +[ -f /etc/samba/smb.conf ] || exit 0 + +RETVAL=0 + + +start() { + KIND="Winbind" + echo -n $"Starting $KIND services: " + daemon winbindd "$WINBINDOPTIONS" + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/winbindd || RETVAL=1 + return $RETVAL +} + +stop() { + echo + KIND="Winbind" + echo -n $"Shutting down $KIND services: " + killproc winbindd + RETVAL=$? + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/winbindd + echo "" + return $RETVAL +} + +restart() { + stop + start +} + +reload() { + echo -n $"Reloading smb.conf file: " + killproc winbindd -HUP + RETVAL=$? + echo + return $RETVAL +} + +rhstatus() { + status winbindd +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + reload) + reload + ;; + status) + rhstatus + ;; + condrestart) + [ -f /var/lock/subsys/winbindd ] && restart || : + ;; + *) + echo $"Usage: $0 {start|stop|restart|reload|status|condrestart}" + exit 1 +esac + +exit $? diff --git a/source3/Makefile.in b/source3/Makefile.in index a660718c37..63dfeeec5f 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -9,7 +9,6 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ -mandir=@mandir@ LIBS=@LIBS@ CC=@CC@ @@ -1310,12 +1309,16 @@ installman: installdirs showlayout: @echo "Samba will be installed into:" - @echo " basedir: $(BASEDIR)" - @echo " bindir: $(BINDIR)" - @echo " sbindir: $(SBINDIR)" - @echo " libdir: $(LIBDIR)" - @echo " vardir: $(VARDIR)" - @echo " mandir: $(MANDIR)" + @echo " basedir: $(BASEDIR)" + @echo " bindir: $(BINDIR)" + @echo " sbindir: $(SBINDIR)" + @echo " libdir: $(LIBDIR)" + @echo " vardir: $(VARDIR)" + @echo " mandir: $(MANDIR)" + @echo " privatedir: $(PRIVATE_DIR)" + @echo " configdir: $(CONFIGDIR)" + @echo " lockdir: $(LOCKDIR)" + @echo " piddir: $(PIDDIR)" uninstall: uninstallman uninstallbin uninstallscripts uninstallmodules diff --git a/source3/configure.in b/source3/configure.in index 5c4580f14a..b5b5a7609f 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -17,8 +17,9 @@ AC_PREFIX_DEFAULT(/usr/local/samba) AC_ARG_WITH(fhs, [ --with-fhs Use FHS-compliant paths (default=no)], configdir="${sysconfdir}/samba" - lockdir="\${VARDIR}/cache/samba" - piddir="\${VARDIR}/run/samba" + lockdir="\${VARDIR}/lib/samba" + piddir="\${VARDIR}/run" + mandir="\${prefix}/share/man" logfilebase="\${VARDIR}/log/samba" privatedir="\${CONFIGDIR}/private" libdir="\${prefix}/lib/samba" @@ -27,6 +28,7 @@ AC_ARG_WITH(fhs, logfilebase="\${VARDIR}" lockdir="\${VARDIR}/locks" piddir="\${VARDIR}/locks" + mandir="\${prefix}/man" privatedir="\${prefix}/private" swatdir="\${prefix}/swat") @@ -78,6 +80,23 @@ AC_ARG_WITH(piddir, ;; esac]) +################################################# +# set pid directory location +AC_ARG_WITH(piddir, +[ --with-mandir=DIR Where to put man pages ($ac_default_prefix/man)], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-mandir called without argument - will use default]) + ;; + * ) + piddir="$withval" + ;; + esac]) + + ################################################# # set SWAT directory location AC_ARG_WITH(swatdir, @@ -148,6 +167,7 @@ done AC_SUBST(configdir) AC_SUBST(lockdir) AC_SUBST(piddir) +AC_SUBST(mandir) AC_SUBST(logfilebase) AC_SUBST(privatedir) AC_SUBST(swatdir) diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index fba427536c..1c5d6acf51 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -691,8 +691,8 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) goto tryagain; } - DEBUG(10, ("got gid %lu for group %x\n", (unsigned long)group_gid, - name_list[ent->sam_entry_index].rid)); + DEBUG(10, ("got gid %lu for group %lu\n", (unsigned long)group_gid, + (unsigned long)name_list[ent->sam_entry_index].rid)); /* Fill in group entry */ -- cgit From c5914a4b552ba0d6bf09305ae539d469847804a4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Dec 2003 22:32:55 +0000 Subject: IRIX spinlock patch from James Peach . Jeremy. (This used to be commit 04abff372b8939bd33c6dceb48baac9fdb7e27b6) --- source3/configure.in | 8 ++++++++ source3/tdb/spinlock.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/source3/configure.in b/source3/configure.in index b5b5a7609f..a5db46bc18 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2016,6 +2016,14 @@ if test x"$samba_cv_SYSCONF_SC_NGROUPS_MAX" = x"yes"; then AC_DEFINE(SYSCONF_SC_NGROUPS_MAX,1,[Whether sysconf(_SC_NGROUPS_MAX) is available]) fi +AC_CACHE_CHECK([for sysconf(_SC_NPROC_ONLN)],samba_cv_SYSCONF_SC_NPROC_ONLN,[ +AC_TRY_RUN([#include +main() { exit(sysconf(_SC_NPROC_ONLN) == -1 ? 1 : 0); }], +samba_cv_SYSCONF_SC_NPROC_ONLN=yes,samba_cv_SYSCONF_SC_NPROC_ONLN=no,samba_cv_SYSCONF_SC_NPROC_ONLN=cross)]) +if test x"$samba_cv_SYSCONF_SC_NPROC_ONLN" = x"yes"; then + AC_DEFINE(SYSCONF_SC_NPROC_ONLN,1,[Whether sysconf(_SC_NPROC_ONLN) is available]) +fi + AC_CACHE_CHECK([for root],samba_cv_HAVE_ROOT,[ AC_TRY_RUN([main() { exit(getuid() != 0); }], samba_cv_HAVE_ROOT=yes,samba_cv_HAVE_ROOT=no,samba_cv_HAVE_ROOT=cross)]) diff --git a/source3/tdb/spinlock.c b/source3/tdb/spinlock.c index 3fddeafb2c..3b3ebefded 100644 --- a/source3/tdb/spinlock.c +++ b/source3/tdb/spinlock.c @@ -143,6 +143,47 @@ static inline int __spin_is_locked(spinlock_t *lock) return (*lock != 1); } +#elif defined(MIPS_SPINLOCKS) && defined(sgi) && (_COMPILER_VERSION >= 730) + +/* Implement spinlocks on IRIX using the MIPSPro atomic fetch operations. See + * sync(3) for the details of the intrinsic operations. + * + * "sgi" and "_COMPILER_VERSION" are always defined by MIPSPro. + */ + +#if defined(STANDALONE) + +/* MIPSPro 7.3 has "__inline" as an extension, but not "inline. */ +#define inline __inline + +#endif /* STANDALONE */ + +/* Returns 0 if the lock is acquired, EBUSY otherwise. */ +static inline int __spin_trylock(spinlock_t *lock) +{ + unsigned int val; + val = __lock_test_and_set(lock, 1); + return val == 0 ? 0 : EBUSY; +} + +static inline void __spin_unlock(spinlock_t *lock) +{ + __lock_release(lock); +} + +static inline void __spin_lock_init(spinlock_t *lock) +{ + __lock_release(lock); +} + +/* Returns 1 if the lock is held, 0 otherwise. */ +static inline int __spin_is_locked(spinlock_t *lock) +{ + unsigned int val; + val = __add_and_fetch(lock, 0); + return val; +} + #elif defined(MIPS_SPINLOCKS) static inline unsigned int load_linked(unsigned long addr) @@ -221,7 +262,11 @@ static void yield_cpu(void) static int this_is_smp(void) { +#if defined(HAVE_SYSCONF) && defined(SYSCONF_SC_NPROC_ONLN) + return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0; +#else return 0; +#endif } /* -- cgit From 1665e8cabab3ee3f74f5fb1805e5593a7aa3cf00 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 10 Dec 2003 14:10:39 +0000 Subject: patch from TAKEDA yasuma to bypass any missing language files (This used to be commit c65f63be1eb8bb9350cc7e843c858050c5ce5095) --- source3/script/installswat.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source3/script/installswat.sh b/source3/script/installswat.sh index 534c2d761f..027ca35110 100755 --- a/source3/script/installswat.sh +++ b/source3/script/installswat.sh @@ -29,6 +29,9 @@ done for ln in $LANGS; do for f in $SRCDIR../swat/$ln/images/*.gif; do + if [ ! -f $f ] ; then + continue + fi FNAME=$SWATDIR/$ln/images/`basename $f` echo $FNAME cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges? @@ -38,6 +41,9 @@ for ln in $LANGS; do # Install html help for f in $SRCDIR../swat/$ln/help/*.html; do + if [ ! -f $f ] ; then + continue + fi FNAME=$SWATDIR/$ln/help/`basename $f` echo $FNAME if [ "x$BOOKDIR" = "x" ]; then @@ -54,6 +60,9 @@ for ln in $LANGS; do # Install "server-side" includes for f in $SRCDIR../swat/$ln/include/*.html; do + if [ ! -f $f ] ; then + continue + fi FNAME=$SWATDIR/$ln/include/`basename $f` echo $FNAME cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges? -- cgit From caf641f2d2aa8edecd3f4d0a9b234e614b43f7e6 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 10 Dec 2003 16:01:20 +0000 Subject: Fix #558 -- support ISO-8859-1 internally. Makes Solaris users a bit happier (This used to be commit 808fc7e9d52ccc61ceb56821f6b977936817b88b) --- source3/lib/iconv.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/source3/lib/iconv.c b/source3/lib/iconv.c index 9f6db79ee2..b0c13a5ee6 100644 --- a/source3/lib/iconv.c +++ b/source3/lib/iconv.c @@ -53,6 +53,7 @@ static size_t ascii_pull(void *,char **, size_t *, char **, size_t *); static size_t ascii_push(void *,char **, size_t *, char **, size_t *); +static size_t latin1_push(void *,char **, size_t *, char **, size_t *); static size_t utf8_pull(void *,char **, size_t *, char **, size_t *); static size_t utf8_push(void *,char **, size_t *, char **, size_t *); static size_t ucs2hex_pull(void *,char **, size_t *, char **, size_t *); @@ -64,6 +65,7 @@ static struct charset_functions builtin_functions[] = { {"UTF8", utf8_pull, utf8_push}, {"ASCII", ascii_pull, ascii_push}, {"646", ascii_pull, ascii_push}, + {"ISO-8859-1", ascii_pull, latin1_push}, {"UCS2-HEX", ucs2hex_pull, ucs2hex_push}, {NULL, NULL, NULL} }; @@ -354,6 +356,32 @@ static size_t ascii_push(void *cd, char **inbuf, size_t *inbytesleft, return ir_count; } +static size_t latin1_push(void *cd, char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + int ir_count=0; + + while (*inbytesleft >= 2 && *outbytesleft >= 1) { + (*outbuf)[0] = (*inbuf)[0]; + if ((*inbuf)[1]) ir_count++; + (*inbytesleft) -= 2; + (*outbytesleft) -= 1; + (*inbuf) += 2; + (*outbuf) += 1; + } + + if (*inbytesleft == 1) { + errno = EINVAL; + return -1; + } + + if (*inbytesleft > 1) { + errno = E2BIG; + return -1; + } + + return ir_count; +} static size_t ucs2hex_pull(void *cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) -- cgit From b90d6b16e4175526c5112b9541d7d509d5a64edf Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 10 Dec 2003 16:42:44 +0000 Subject: more group lookup access fixes on the neverending bug 281 (This used to be commit 975ac6f5aa4d8d709733757e4e003f3c551fc9ba) --- source3/groupdb/mapping.c | 28 +++++++++++++++++++++++----- source3/passdb/passdb.c | 22 ++++++++++++++++------ source3/rpc_server/srv_samr_nt.c | 7 ++++++- source3/rpc_server/srv_util.c | 14 ++++---------- 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index b1c260581e..08ac6a25a5 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -504,7 +504,8 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) { struct group *grp; - + BOOL ret; + if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping")); return(False); @@ -513,7 +514,12 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) DEBUG(10, ("get_domain_group_from_sid\n")); /* if the group is NOT in the database, it CAN NOT be a domain group */ - if(!pdb_getgrsid(map, sid)) + + become_root(); + ret = pdb_getgrsid(map, sid); + unbecome_root(); + + if ( !ret ) return False; DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n")); @@ -547,14 +553,19 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) { + BOOL ret; + if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping")); return(False); } /* The group is in the mapping table */ + become_root(); + ret = pdb_getgrsid(map, sid); + unbecome_root(); - if( !pdb_getgrsid(map, sid) ) + if ( !ret ) return False; if ( (map->sid_name_use != SID_NAME_ALIAS) @@ -564,7 +575,7 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) return False; } -#if 0 /* JERRY */ +#if 1 /* JERRY */ /* local groups only exist in the group mapping DB so this is not necessary */ @@ -572,6 +583,7 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) /* the group isn't in the mapping table. * make one based on the unix information */ uint32 alias_rid; + struct group *grp; sid_peek_rid(&sid, &alias_rid); map->gid=pdb_group_rid_to_gid(alias_rid); @@ -599,13 +611,19 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map) { struct group *grp; + BOOL ret; + if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping")); return(False); } - if(!pdb_getgrsid(map, sid)) + become_root(); + ret = pdb_getgrsid(map, sid); + unbecome_root(); + + if ( !ret ) return False; if (map->sid_name_use!=SID_NAME_WKN_GRP) { diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 82b1f9a0eb..b0c2430c09 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -707,6 +707,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use uint32 rid; SAM_ACCOUNT *sam_account = NULL; GROUP_MAP map; + BOOL ret; if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){ DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n", @@ -736,9 +737,10 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use /* see if the passdb can help us with the name of the user */ + /* BEING ROOT BLLOCK */ become_root(); if (pdb_getsampwsid(sam_account, sid)) { - unbecome_root(); + unbecome_root(); /* -----> EXIT BECOME_ROOT() */ fstrcpy(name, pdb_get_username(sam_account)); *psid_name_use = SID_NAME_USER; @@ -746,10 +748,13 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use return True; } - unbecome_root(); pdb_free_sam(&sam_account); - - if (pdb_getgrsid(&map, *sid)) { + + ret = pdb_getgrsid(&map, *sid); + unbecome_root(); + /* END BECOME_ROOT BLOCK */ + + if ( ret ) { if (map.gid!=(gid_t)-1) { DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid)); } else { @@ -1233,6 +1238,7 @@ BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_ { uint32 rid; GROUP_MAP group; + BOOL ret; *name_type = SID_NAME_UNKNOWN; @@ -1241,8 +1247,12 @@ BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_ /* we don't need to disable winbindd since the gid is stored in the GROUP_MAP object */ - - if ( !pdb_getgrsid(&group, *psid) ) { + + become_root(); + pdb_getgrsid(&group, *psid); + unbecome_root(); + + if ( !ret ) { /* fallback to rid mapping if enabled */ diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 7f57a9fc9d..c84e288a4b 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -1246,6 +1246,7 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM DOM_SID sid; GROUP_MAP map; uint32 acc_granted; + BOOL ret; r_u->status = NT_STATUS_OK; @@ -1262,7 +1263,11 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM !sid_check_is_in_builtin(&sid)) return NT_STATUS_OBJECT_TYPE_MISMATCH; - if (!pdb_getgrsid(&map, sid)) + become_root(); + ret = pdb_getgrsid(&map, sid); + unbecome_root(); + + if ( !ret ) return NT_STATUS_NO_SUCH_ALIAS; switch (q_u->switch_level) { diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index c2395e6fae..504e6a83c0 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -147,8 +147,6 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui return NT_STATUS_UNSUCCESSFUL; } - become_root(); - for (i=0;i Date: Wed, 10 Dec 2003 21:14:39 +0000 Subject: Fix UNISTR2 length bug in LsaQueryInfo(3) that cause SID resolution to fail on local files on on domain members; bug 875 (This used to be commit a5c5dde1c34ba44f8d9bbb38720a089a6d61806c) --- source3/bin/.cvsignore | 1 + source3/include/rpc_misc.h | 2 +- source3/rpc_parse/parse_misc.c | 2 +- source3/rpc_server/srv_lsa_nt.c | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source3/bin/.cvsignore b/source3/bin/.cvsignore index 31af1fe22d..013a5ba6c1 100644 --- a/source3/bin/.cvsignore +++ b/source3/bin/.cvsignore @@ -52,3 +52,4 @@ log2pcap wbinfo winbindd wrepld +tdbdump diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h index aaaad55c20..29ae212185 100644 --- a/source3/include/rpc_misc.h +++ b/source3/include/rpc_misc.h @@ -403,5 +403,5 @@ typedef struct buffer4_info } BUFFER4; -enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_TERMINATE = 2 }; +enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_TERMINATE = 2, UNI_BROKEN_NON_NULL = 3 }; #endif /* _RPC_MISC_H */ diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 7cd3c795e6..b34efa6667 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -942,7 +942,7 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags) str->uni_max_len = num_chars; str->offset = 0; str->uni_str_len = num_chars; - if (num_chars && (flags == UNI_MAXLEN_TERMINATE)) + if ( num_chars && ((flags == UNI_MAXLEN_TERMINATE) || (flags == UNI_BROKEN_NON_NULL)) ) str->uni_max_len++; } diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 8785cce789..01a31dcfe5 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -66,7 +66,7 @@ static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_si /* this string is supposed to be non-null terminated. */ /* But the maxlen in this UNISTR2 must include the terminating null. */ - init_unistr2(&d_q->uni_domain_name, dom_name, UNI_MAXLEN_TERMINATE); + init_unistr2(&d_q->uni_domain_name, dom_name, UNI_BROKEN_NON_NULL); /* * I'm not sure why this really odd combination of length -- cgit From ef1c713322ea1f4e994c262192f1b8c3518cc8c7 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Thu, 11 Dec 2003 10:31:20 +0000 Subject: Fix uninitialized variable in passdb code. Reported by Andy Polyakov (This used to be commit ca21dd3bb682700d628e9fc1aeedd1594cda3094) --- source3/passdb/passdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index b0c2430c09..f4acb2fbf6 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1249,7 +1249,7 @@ BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_ the GROUP_MAP object */ become_root(); - pdb_getgrsid(&group, *psid); + ret = pdb_getgrsid(&group, *psid); unbecome_root(); if ( !ret ) { -- cgit From da3a5ad98a03565525b496642a82c570af64f0b2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 11 Dec 2003 15:35:44 +0000 Subject: fixed bad formal parameter type in get_static(); patch Andy Polyakov (This used to be commit 67d893701f09f29e8af56cd98f04131658b39713) --- source3/nsswitch/wins.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c index 0fc4e46cdb..779d1b2c6c 100644 --- a/source3/nsswitch/wins.c +++ b/source3/nsswitch/wins.c @@ -265,7 +265,7 @@ int lookup(nsd_file_t *rq) are the pointers passed in by the C library to the _nss_*_* functions. */ -static char *get_static(char **buffer, int *buflen, int len) +static char *get_static(char **buffer, size_t *buflen, int len) { char *result; -- cgit From 0b88121c7898e85837f32c98b445c9c4863b3fa8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Dec 2003 19:59:05 +0000 Subject: Patch from James Peach . Remove the MAX_CONNECTIONS limit by increasing bitmap size. Limited by "max connections" parameter. Bug #716. Jeremy. (This used to be commit 0be57a2eb015f832c6bb6d84525719a3d632f741) --- source3/lib/bitmap.c | 14 ++++++++++++++ source3/smbd/conn.c | 41 ++++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/source3/lib/bitmap.c b/source3/lib/bitmap.c index 1023dd6541..3fa20cdd11 100644 --- a/source3/lib/bitmap.c +++ b/source3/lib/bitmap.c @@ -83,6 +83,20 @@ struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n) return bm; } +/**************************************************************************** +copy as much of the source bitmap as will fit in the destination bitmap. +****************************************************************************/ + +int bitmap_copy(struct bitmap * const dst, const struct bitmap * const src) +{ + int count = MIN(dst->n, src->n); + + SMB_ASSERT(dst->b != src->b); + memcpy(dst->b, src->b, sizeof(dst->b[0])*(count+31)/32); + + return count; +} + /**************************************************************************** set a bit in a bitmap ****************************************************************************/ diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index eb2d2bbcbf..289b7d611d 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -21,11 +21,11 @@ #include "includes.h" -/* set these to define the limits of the server. NOTE These are on a - per-client basis. Thus any one machine can't connect to more than - MAX_CONNECTIONS services, but any number of machines may connect at - one time. */ -#define MAX_CONNECTIONS 128 +/* The connections bitmap is expanded in increments of BITMAP_BLOCK_SZ. The + * maximum size of the bitmap is the largest positive integer, but you will hit + * the "max connections" limit, looong before that. + */ +#define BITMAP_BLOCK_SZ 128 static connection_struct *Connections; @@ -38,7 +38,7 @@ init the conn structures ****************************************************************************/ void conn_init(void) { - bmap = bitmap_allocate(MAX_CONNECTIONS); + bmap = bitmap_allocate(BITMAP_BLOCK_SZ); } /**************************************************************************** @@ -96,12 +96,35 @@ connection_struct *conn_new(void) TALLOC_CTX *mem_ctx; connection_struct *conn; int i; + int find_offset = 1; - i = bitmap_find(bmap, 1); +find_again: + i = bitmap_find(bmap, find_offset); if (i == -1) { - DEBUG(1,("ERROR! Out of connection structures\n")); - return NULL; + /* Expand the connections bitmap. */ + int oldsz = bmap->n; + int newsz = bmap->n + BITMAP_BLOCK_SZ; + struct bitmap * nbmap; + + if (newsz <= 0) { + /* Integer wrap. */ + DEBUG(0,("ERROR! Out of connection structures\n")); + return NULL; + } + + DEBUG(4,("resizing connections bitmap from %d to %d\n", + oldsz, newsz)); + + nbmap = bitmap_allocate(newsz); + + bitmap_copy(nbmap, bmap); + bitmap_free(bmap); + + bmap = nbmap; + find_offset = oldsz; /* Start next search in the new portion. */ + + goto find_again; } if ((mem_ctx=talloc_init("connection_struct"))==NULL) { -- cgit From 525f7255f4c8ce478b3e5bcc5078c85482213016 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Dec 2003 20:54:55 +0000 Subject: Correctly detect in-memory krb5 keytab support. Fix for bug #863 from gschafer@zip.com.au (Greg Schafer). Jeremy. (This used to be commit 25d91f8d8c4e3bd8237716052b53350587ffb8dc) --- source3/configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index a5db46bc18..62bba1ea13 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2728,8 +2728,8 @@ if test x"$with_ads_support" != x"no"; then exit(0); exit(1); }], - samba_cv_HAVE_MEMORY_KEYTAB=no, - samba_cv_HAVE_MEMORY_KEYTAB=yes)]) + samba_cv_HAVE_MEMORY_KEYTAB=yes, + samba_cv_HAVE_MEMORY_KEYTAB=no)]) if test x"$samba_cv_HAVE_MEMORY_KEYTAB" = x"yes"; then AC_DEFINE(HAVE_MEMORY_KEYTAB,1, -- cgit From 4d0dcebb83324b9912b908cec3308a1c77da2230 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 11 Dec 2003 22:31:00 +0000 Subject: fix bug that prevent --mandir from overriding the defaults given in the --with-fhs macro (This used to be commit 824218d086d90f6fcf3789e8e87f047e2da55c25) --- source3/configure.in | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 62bba1ea13..4d681c0d87 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -28,7 +28,6 @@ AC_ARG_WITH(fhs, logfilebase="\${VARDIR}" lockdir="\${VARDIR}/locks" piddir="\${VARDIR}/locks" - mandir="\${prefix}/man" privatedir="\${prefix}/private" swatdir="\${prefix}/swat") @@ -80,23 +79,6 @@ AC_ARG_WITH(piddir, ;; esac]) -################################################# -# set pid directory location -AC_ARG_WITH(piddir, -[ --with-mandir=DIR Where to put man pages ($ac_default_prefix/man)], -[ case "$withval" in - yes|no) - # - # Just in case anybody calls it without argument - # - AC_MSG_WARN([--with-mandir called without argument - will use default]) - ;; - * ) - piddir="$withval" - ;; - esac]) - - ################################################# # set SWAT directory location AC_ARG_WITH(swatdir, @@ -167,7 +149,6 @@ done AC_SUBST(configdir) AC_SUBST(lockdir) AC_SUBST(piddir) -AC_SUBST(mandir) AC_SUBST(logfilebase) AC_SUBST(privatedir) AC_SUBST(swatdir) -- cgit From 3bdde6f8450f1f1f28dec38c0607ca2cb49d677b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Dec 2003 20:15:47 +0000 Subject: Fix detection of elements in in-memory keytab code. Jeremy. (This used to be commit c208ea44aa4cc8c0cde6aa02d98d87f36aed9589) --- source3/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index 4d681c0d87..c692569e36 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2720,7 +2720,7 @@ if test x"$with_ads_support" != x"no"; then AC_CACHE_CHECK([for key in krb5_keytab_entry], samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY,[ AC_TRY_COMPILE([#include ], - [krb5_keytab_entry entry; entry.key = NULL;], + [krb5_keytab_entry entry; krb5_keyblock e; entry.key = e;], samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY=yes, samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY=no)]) -- cgit From 7ec4ae7544162eb7c49b16515bed00ff21da797a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Dec 2003 22:54:41 +0000 Subject: Fix for bug #815. Make plaintext unicode passwords work with NT4.x Jeremy. (This used to be commit 29bac18b6971f459c3cb138366ae493d5805f643) --- source3/smbd/sesssetup.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index da48c81fc1..e9cfa47d0c 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -689,11 +689,17 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, nt_resp = data_blob(p+passlen1, passlen2); } else { pstring pass; - BOOL unic; - unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS; - srvstr_pull(inbuf, pass, smb_buf(inbuf), - sizeof(pass), unic ? passlen2 : passlen1, - STR_TERMINATE); + BOOL unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS; + + if ((ra_type == RA_WINNT) && (passlen2 == 0) && unic && passlen1) { + /* NT4.0 stuffs up plaintext unicode password lengths... */ + srvstr_pull(inbuf, pass, smb_buf(inbuf) + 1, + sizeof(pass), passlen1, STR_TERMINATE); + } else { + srvstr_pull(inbuf, pass, smb_buf(inbuf), + sizeof(pass), unic ? passlen2 : passlen1, + STR_TERMINATE); + } plaintext_password = data_blob(pass, strlen(pass)+1); } -- cgit From 24dff2061e639f08e4f7bba1ebec3bcb41dfcbaa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Dec 2003 01:43:52 +0000 Subject: Fix from ndb@theghet.to to allow an existing LDAP machine account to be re-used, rather than created from scratch. Jeremy. (This used to be commit 1bcc4c244dd127643c66ed75550f405e90c99c76) --- source3/libads/ldap.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 775a504f2b..6e40089b70 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -998,6 +998,14 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL}; char *psp, *psp2; unsigned acct_control; + unsigned exists=0; + LDAPMessage *res; + + status = ads_find_machine_acct(ads, (void **)&res, hostname); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { + DEBUG(0, ("Host account for %s already exists - modifying old account\n", hostname)); + exists=1; + } if (!(ctx = talloc_init("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1045,18 +1053,23 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(mods = ads_init_mods(ctx))) goto done; - - ads_mod_str(ctx, &mods, "cn", hostname); - ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); - ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + + if (!exists) { + ads_mod_str(ctx, &mods, "cn", hostname); + ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + } + ads_mod_str(ctx, &mods, "dNSHostName", hostname); ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); - ads_mod_str(ctx, &mods, "dNSHostName", hostname); - ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); ads_mod_str(ctx, &mods, "operatingSystemVersion", SAMBA_VERSION_STRING); - ret = ads_gen_add(ads, new_dn, mods); + if (!exists) + ret = ads_gen_add(ads, new_dn, mods); + else + ret = ads_gen_mod(ads, new_dn, mods); if (!ADS_ERR_OK(ret)) goto done; @@ -1065,11 +1078,13 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, * it shouldn't be mandatory and probably we just * don't have enough rights to do it. */ - status = ads_set_machine_sd(ads, hostname, new_dn); - - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", - ads_errstr(status))); + if (!exists) { + status = ads_set_machine_sd(ads, hostname, new_dn); + + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", + ads_errstr(status))); + } } done: talloc_destroy(ctx); @@ -1303,6 +1318,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, host = strdup(hostname); strlower_m(host); + /* status = ads_find_machine_acct(ads, (void **)&res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { DEBUG(0, ("Host account for %s already exists - deleting old account\n", host)); @@ -1313,6 +1329,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, return status; } } + */ status = ads_add_machine_acct(ads, host, account_type, org_unit); if (!ADS_ERR_OK(status)) { -- cgit From 86f53a0da1e0fab1ce8daf6433c803ebd61181d7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 16 Dec 2003 18:36:05 +0000 Subject: make sure we delete the group mapping before calling the delete group script; patch from Jianliang Lu (This used to be commit 66edeb855e7d7a0bfa20cbe93275c86880bd453d) --- source3/rpc_server/srv_samr_nt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index c84e288a4b..4d4dfed47c 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3827,6 +3827,10 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S if ( (grp=getgrgid(gid)) == NULL) return NT_STATUS_NO_SUCH_GROUP; + /* delete mapping first */ + if(!pdb_delete_group_mapping_entry(group_sid)) + return NT_STATUS_ACCESS_DENIED; + /* we can delete the UNIX group */ smb_delete_group(grp->gr_name); @@ -3834,8 +3838,6 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S if ( (grp=getgrgid(gid)) != NULL) return NT_STATUS_ACCESS_DENIED; - if(!pdb_delete_group_mapping_entry(group_sid)) - return NT_STATUS_ACCESS_DENIED; if (!close_policy_hnd(p, &q_u->group_pol)) return NT_STATUS_OBJECT_NAME_INVALID; -- cgit From 18bc0b2bc231825dc650c4e6cef73e277d3f2a54 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 17 Dec 2003 06:18:41 +0000 Subject: Make sure we correctly generate the lm session key. This fixes a problem joining a Samba domain from a vanilla win2k client that doesn't set the NTLMSSP_NEGOTIATE_NTLM2 flag. Reported on samba ml as "decode_pw: incorrect password length" when handling a samr_set_userinfo(23 or 24) RPC. (This used to be commit 14558c942beb05cd12c0e40c1bb30c3dcde8ce48) --- source3/libsmb/ntlmssp.c | 8 ++++++-- source3/libsmb/smbencrypt.c | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index ca1aa67403..3cfd6d2043 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -660,6 +660,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); hmac_md5(nt_session_key.data, session_nonce, sizeof(session_nonce), session_key.data); + DEBUG(10,("NTLM2 session key set\n")); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } @@ -667,12 +668,14 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, if (lm_session_key.data && lm_session_key.length >= 8 && ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - SMBsesskeygen_lmv1(lm_session_key.data, ntlmssp_state->lm_resp.data, + SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, session_key.data); + DEBUG(10,("LM KEY session key set\n")); dump_data_pw("LM session key:\n", session_key.data, session_key.length); } } else if (nt_session_key.data) { session_key = nt_session_key; + DEBUG(10,("unmodified session key set\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); } @@ -695,7 +698,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, encrypted_session_key.data, encrypted_session_key.length); - dump_data_pw("KEY_EXCH session key:\n", session_key.data, session_key.length); + dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, + encrypted_session_key.length); } } else { ntlmssp_state->session_key = session_key; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 2d02a23394..cfcc24a1df 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -325,6 +325,26 @@ void SMBsesskeygen_lmv1(const uchar lm_hash[16], #endif } +void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], + const uchar lm_resp[24], /* only uses 8 */ + uint8 sess_key[16]) +{ + uchar p24[24]; + uchar partial_lm_hash[16]; + + memcpy(partial_lm_hash, lm_hash, 8); + memset(partial_lm_hash + 8, 0xbd, 8); + + SMBOWFencrypt(partial_lm_hash, lm_resp, p24); + + memcpy(sess_key, p24, 16); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_lmv1_jerry:\n")); + dump_data(100, sess_key, 16); +#endif +} + DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, const char *domain) { -- cgit From 776605c768e9c343af2c9897162724acc08d4dae Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Dec 2003 20:11:35 +0000 Subject: Tidyup debug message in ntlmssp code. Add brackets around dodgy if statement. Jeremy (This used to be commit 6cd0f6e7c0a28ddccf55acb1e411e5ed5bd3cf47) --- source3/libsmb/ntlmssp.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 3cfd6d2043..10f2983180 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -330,7 +330,7 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->unicode = False; } - if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY && allow_lm) { + if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) { /* other end forcing us to use LM */ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; ntlmssp_state->use_ntlmv2 = False; @@ -660,9 +660,13 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); hmac_md5(nt_session_key.data, session_nonce, sizeof(session_nonce), session_key.data); - DEBUG(10,("NTLM2 session key set\n")); + DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n")); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); + }else { + data_blob_free(&encrypted_session_key); + DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); + return NT_STATUS_INVALID_PARAMETER; } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { if (lm_session_key.data && lm_session_key.length >= 8 && @@ -670,13 +674,21 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, session_key.data); - DEBUG(10,("LM KEY session key set\n")); + DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); dump_data_pw("LM session key:\n", session_key.data, session_key.length); + } else { + data_blob_free(&encrypted_session_key); + DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); + return NT_STATUS_INVALID_PARAMETER; } } else if (nt_session_key.data) { session_key = nt_session_key; - DEBUG(10,("unmodified session key set\n")); + DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + } else { + data_blob_free(&encrypted_session_key); + DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified nt session key.\n")); + return NT_STATUS_INVALID_PARAMETER; } /* With KEY_EXCH, the client supplies the proposed session key, @@ -1026,7 +1038,7 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); + DEBUG(0,("ntlmssp_client_start: talloc failed!\n")); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } -- cgit From 80222a3a92209394e35edaee5f5773c72d0e1fdf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Dec 2003 21:57:29 +0000 Subject: Add in comments explaining NTLMv2 selection. Use lm session key if that's all there is. Jeremy. (This used to be commit 3e6abeffe176cdba43d251f55f3b7aecd8fa55b1) --- source3/libsmb/ntlmssp.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 10f2983180..7b821da0fd 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -645,7 +645,15 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } } + /* + * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth + * is required (by "ntlm auth = no" and "lm auth = no" being set in the + * smb.conf file) and no NTLMv2 response was sent then the password check + * will fail here. JRA. + */ + /* Finally, actually ask if the password is OK */ + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) { data_blob_free(&encrypted_session_key); return nt_status; @@ -685,9 +693,13 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key = nt_session_key; DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + } else if (lm_session_key.data) { + session_key = lm_session_key; + DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n")); + dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); } else { data_blob_free(&encrypted_session_key); - DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified nt session key.\n")); + DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n")); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 99b2bbfaa26139e6c27db8bebcd10719872bcbe2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Dec 2003 00:33:27 +0000 Subject: * add a few useful debug lines * fix bug involving Win9x clients. Make sure we save the right case for the located username in fill_sam_account() (This used to be commit d22b4097d4c2bde7989af31ccb572871c6e63424) --- source3/auth/auth_util.c | 36 ++++++++++++++++++++++++++++-------- source3/auth/auth_winbind.c | 3 ++- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 3dc0fdbe46..c474049617 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -926,21 +926,38 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, fstring dom_user; struct passwd *passwd; - fstr_sprintf(dom_user, "%s%s%s", - domain, lp_winbind_separator(), username); + fstr_sprintf(dom_user, "%s%s%s", domain, lp_winbind_separator(), + username); passwd = Get_Pwnam(dom_user); + + if ( passwd ) { + char *p; + + /* make sure we get the case of the username correct */ + /* work around 'winbind use default domain = yes' */ + + p = strchr( passwd->pw_name, *lp_winbind_separator() ); + if ( !p ) + fstr_sprintf(dom_user, "%s%s%s", domain, + lp_winbind_separator(), passwd->pw_name); + else + fstrcpy( dom_user, passwd->pw_name ); + } + else { + /* if the lookup for DOMAIN\username failed, try again + with just 'username'. This is need for accessing the server + as a trust user that actually maps to a local account */ - /* if the lookup for DOMAIN\username failed, try again - with just 'username'. This is need for accessing the server - as a trust user that actually maps to a local account */ - - if ( !passwd ) { fstrcpy( dom_user, username ); passwd = Get_Pwnam( dom_user ); + + /* make sure we get the case of the username correct */ + if ( passwd ) + fstrcpy( dom_user, passwd->pw_name ); } - if (passwd == NULL) + if ( !passwd ) return NT_STATUS_NO_SUCH_USER; *uid = passwd->pw_uid; @@ -953,6 +970,9 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, --jerry */ *found_username = talloc_strdup(mem_ctx, dom_user); + + DEBUG(5,("fill_sam_account: located username was [%s]\n", + *found_username)); return pdb_init_sam_pw(sam_account, passwd); } diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c index d09987ba37..0e2820313e 100644 --- a/source3/auth/auth_winbind.c +++ b/source3/auth/auth_winbind.c @@ -76,7 +76,8 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, } if (strequal(user_info->domain.str, get_global_sam_name())) { - DEBUG(3,("check_winbind_security: Not using winbind, requested domain was for this SAM.\n")); + DEBUG(3,("check_winbind_security: Not using winbind, requested domain [%s] was for this SAM.\n", + user_info->domain.str)); return NT_STATUS_NOT_IMPLEMENTED; } -- cgit From c24ab7ccaecf94022a9ff303ab34c724622384d3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 22 Dec 2003 11:12:12 +0000 Subject: Patch from Jianliang Lu j.lu@tiesse.com to manage Power Users group. Jeremy. (This used to be commit 72174634aa26c01431ccf85331aaa8b51e70c8ff) --- source3/passdb/util_sam_sid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c index 6e9ccecc9e..3ca54f0529 100644 --- a/source3/passdb/util_sam_sid.c +++ b/source3/passdb/util_sam_sid.c @@ -72,6 +72,7 @@ static const known_sid_users builtin_groups[] = { { BUILTIN_ALIAS_RID_ADMINS, SID_NAME_ALIAS, "Administrators" }, { BUILTIN_ALIAS_RID_USERS, SID_NAME_ALIAS, "Users" }, { BUILTIN_ALIAS_RID_GUESTS, SID_NAME_ALIAS, "Guests" }, + { BUILTIN_ALIAS_RID_POWER_USERS, SID_NAME_ALIAS, "Power Users" }, { BUILTIN_ALIAS_RID_ACCOUNT_OPS, SID_NAME_ALIAS, "Account Operators" }, { BUILTIN_ALIAS_RID_SYSTEM_OPS, SID_NAME_ALIAS, "Server Operators" }, { BUILTIN_ALIAS_RID_PRINT_OPS, SID_NAME_ALIAS, "Print Operators" }, -- cgit From 81e3125db21b0ecc237f740bb8048582aa21b2f0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 22 Dec 2003 21:24:40 +0000 Subject: add well known rid for pre win2k compatible access group; bug 897 (This used to be commit 426a02cf678236f902c143b56eaaf854fca2237f) --- source3/include/rpc_misc.h | 1 + source3/passdb/util_sam_sid.c | 1 + 2 files changed, 2 insertions(+) diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h index 29ae212185..0c6eee3650 100644 --- a/source3/include/rpc_misc.h +++ b/source3/include/rpc_misc.h @@ -63,6 +63,7 @@ #define BUILTIN_ALIAS_RID_REPLICATOR (0x00000228L) #define BUILTIN_ALIAS_RID_RAS_SERVERS (0x00000229L) +#define BUILTIN_ALIAS_RID_PRE_2K_ACCESS (0x0000022aL) /* * Masks for mappings between unix uid and gid types and diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c index 3ca54f0529..f6cc2491a8 100644 --- a/source3/passdb/util_sam_sid.c +++ b/source3/passdb/util_sam_sid.c @@ -79,6 +79,7 @@ static const known_sid_users builtin_groups[] = { { BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" }, { BUILTIN_ALIAS_RID_REPLICATOR, SID_NAME_ALIAS, "Replicator" }, { BUILTIN_ALIAS_RID_RAS_SERVERS, SID_NAME_ALIAS, "RAS Servers" }, + { BUILTIN_ALIAS_RID_PRE_2K_ACCESS, SID_NAME_ALIAS, "Pre-Windows 2000 Compatible Access" }, { 0, (enum SID_NAME_USE)0, NULL}}; /************************************************************************** -- cgit From a7e2a1a9193478b8002ddd55256468a7924d9bb1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 22 Dec 2003 21:26:29 +0000 Subject: correct typo in delete user script; bug 887 (This used to be commit 44ef3dd2b346176e756b5e361a38da19ea93e071) --- examples/smb.conf.default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/smb.conf.default b/examples/smb.conf.default index e7fac80884..839fede123 100644 --- a/examples/smb.conf.default +++ b/examples/smb.conf.default @@ -154,7 +154,7 @@ ; add user script = /usr/sbin/useradd %u ; add group script = /usr/sbin/groupadd %g ; add machine script = /usr/sbin/adduser -n -g machines -c Machine -d /dev/null -s /bin/false %u -; delete user script = /usr/sbin/userdle %u +; delete user script = /usr/sbin/userdel %u ; delete user from group script = /usr/sbin/deluser %u %g ; delete group script = /usr/sbin/groupdel %g -- cgit From cd852878298e2d786f420b68f44eb5ca91e7db42 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 23 Dec 2003 07:33:38 +0000 Subject: Fix for special files being hidden from admins by Dmitry Butskoj Jeremy. (This used to be commit a14259d885291c138d3d62d36737472048840aa6) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 94b605ee8f..bbd79e1659 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -793,7 +793,7 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT */ if (conn->admin_user) - return True; + return False; /* If we can't stat it does not show it */ if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) -- cgit From aeb9021852325ef9faf3b1160ce55afa35a90513 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 24 Dec 2003 10:02:57 +0000 Subject: (merge from 3.0) Thanks to Serassio Guido for noticing issues in our Squid NTLMSSP implementation. We were not resetting the NTLMSSP state for new negotiate packets. Andrew Bartlett (This used to be commit ada064af72e120aacd733245292e988dd696d059) --- source3/utils/ntlm_auth.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 5b1b83d032..132134fd9d 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -340,18 +340,23 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod return; } - if (strlen(buf) > 3) { - request = base64_decode_data_blob(buf + 3); - } else if (strcmp(buf, "YR") == 0) { - request = data_blob(NULL, 0); + if (strncmp(buf, "YR", 2) == 0) { if (ntlmssp_state) ntlmssp_end(&ntlmssp_state); + } else if (strncmp(buf, "KK", 2) == 0) { + } else { DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); return; } + if (strlen(buf) > 3) { + request = base64_decode_data_blob(buf + 3); + } else { + request = data_blob(NULL, 0); + } + if (!ntlmssp_state) { ntlmssp_server_start(&ntlmssp_state); ntlmssp_state->check_password = winbind_pw_check; -- cgit From 40c3f98b8ffa9d3ff6f5cac1122eb11001928dcc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 25 Dec 2003 09:57:39 +0000 Subject: (merge from 3.0) Fix bug 916 - do not perform a + -> space substitution for squid URL encoded strings, only form input in SWAT. Andrew Bartlett (This used to be commit 794ff4da03a3c5b6afa3ee4802f83f04571a5652) --- source3/lib/util_str.c | 5 ----- source3/web/cgi.c | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 1aa33a1a4b..fd339370b3 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1780,11 +1780,6 @@ void rfc1738_unescape(char *buf) { char *p=buf; - while ((p=strchr_m(p,'+'))) - *p = ' '; - - p = buf; - while (p && *p && (p=strchr_m(p,'%'))) { int c1 = p[1]; int c2 = p[2]; diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 07e3ee38fb..8a103fa57f 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -85,6 +85,20 @@ static char *grab_line(FILE *f, int *cl) return ret; } +/** + URL encoded strings can have a '+', which should be replaced with a space + + (This was in rfc1738_unescape(), but that broke the squid helper) +**/ + +void plus_to_space_unescape(char *buf) +{ + char *p=buf; + + while ((p=strchr_m(p,'+'))) + *p = ' '; +} + /*************************************************************************** load all the variables passed to the CGI program. May have multiple variables with the same name and the same or different values. Takes a file parameter @@ -130,7 +144,9 @@ void cgi_load_variables(void) !variables[num_variables].value) continue; + plus_to_space_unescape(variables[num_variables].value); rfc1738_unescape(variables[num_variables].value); + plus_to_space_unescape(variables[num_variables].name); rfc1738_unescape(variables[num_variables].name); #ifdef DEBUG_COMMENTS @@ -161,7 +177,9 @@ void cgi_load_variables(void) !variables[num_variables].value) continue; + plus_to_space_unescape(variables[num_variables].value); rfc1738_unescape(variables[num_variables].value); + plus_to_space_unescape(variables[num_variables].name); rfc1738_unescape(variables[num_variables].name); #ifdef DEBUG_COMMENTS -- cgit From f7650ce10d89a4a602416f1eb76166a0f1d47dbc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 25 Dec 2003 10:10:49 +0000 Subject: abartlet pointed me at the fact that the order and flags in loadparm.c are actually used.... 'afs username map' should not show up in the swat basic view. :-) Maybe I should use swat from time to time.... Volker (This used to be commit 82f47aeca3d376d766efc36fdf2efe158f975484) --- source3/param/loadparm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 949fc0237c..9ed9ad6f21 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -764,7 +764,6 @@ static struct parm_struct parm_table[] = { #ifdef WITH_ADS {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, #endif - {"afs username map", P_USTRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED}, {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED}, @@ -1104,6 +1103,7 @@ static struct parm_struct parm_table[] = { {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED}, {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED}, {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED}, + {"afs username map", P_USTRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED}, {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED}, {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED}, {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE}, -- cgit From ba1d1842fe7c2e35c9a6835bbdbbe7f4616d408c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 25 Dec 2003 22:31:30 +0000 Subject: Fix our parsing of the LDAP url. We get around it as all decent systems seem to have ldap_initialize. Thanks to abartlet for the fix (and the bug in the first place ;-)) Volker (This used to be commit 943e156788ea361cb3ec0ab37a87653494e47f2e) --- source3/lib/smbldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 7bd4c6d7aa..20fa4fbc62 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -548,7 +548,7 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state) p += 4; } - sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port); + sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, host, &port); if (port == 0) { if (strequal(protocol, "ldap")) { -- cgit From 3dba56747d3d34b6ccfeea24f53e38c1554f8f4a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 25 Dec 2003 22:45:15 +0000 Subject: This is metze's LDAP rebind sleep patch: When smb.conf tells us to write to a read-only LDAP replica and we are redirected by the LDAP server, the replication might take some seconds, especially over slow links. This patch delays the next read after a rebind for 'ldap rebind sleep' milliseconds. Metze, thanks for your patience. Volker (This used to be commit 7293550e3642e2553684a7011084dabb0b78fd24) --- source3/include/smbldap.h | 2 ++ source3/lib/smbldap.c | 28 ++++++++++++++++++++++++++++ source3/param/loadparm.c | 4 ++++ 3 files changed, 34 insertions(+) diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 17584c4fe4..14ea2de012 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -138,6 +138,8 @@ struct smbldap_state { time_t last_use; smb_event_id_t event_id; + + struct timeval last_rebind; }; #endif /* HAVE_LDAP */ diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 20fa4fbc62..9dca043584 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -661,6 +661,9 @@ static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, } *methodp = LDAP_AUTH_SIMPLE; } + + gettimeofday(&(ldap_state->last_rebind),NULL); + return 0; } #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ @@ -687,6 +690,8 @@ static int rebindproc_connect_with_state (LDAP *ldap_struct, rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret); + gettimeofday(&(ldap_state->last_rebind),NULL); + return rc; } #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ @@ -909,6 +914,29 @@ int smbldap_search(struct smbldap_state *ldap_state, SMB_ASSERT(ldap_state); + if (ldap_state->last_rebind.tv_sec > 0) { + struct timeval tval; + int tdiff = 0; + int sleep_time = 0; + + ZERO_STRUCT(tval); + + gettimeofday(&tval,NULL); + + tdiff = 1000000 *(tval.tv_sec - ldap_state->last_rebind.tv_sec) + + (tval.tv_usec - ldap_state->last_rebind.tv_usec); + + sleep_time = ((1000*lp_ldap_rebind_sleep())-tdiff)/1000; + + if (sleep_time > 0) { + /* we wait for the LDAP replication */ + DEBUG(5,("smbldap_search: waiting %d milliseconds for LDAP replication.\n",sleep_time)); + msleep(sleep_time); + DEBUG(5,("smbldap_search: go on!\n")); + ZERO_STRUCT(ldap_state->last_rebind); + } + } + if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) { return LDAP_NO_MEMORY; } diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 9ed9ad6f21..1fbd54419c 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -235,6 +235,7 @@ typedef struct char *szLdapAdminDn; char *szAclCompat; int ldap_passwd_sync; + int ldap_rebind_sleep; BOOL ldap_delete_dn; BOOL bMsAddPrinterWizard; BOOL bDNSproxy; @@ -1075,6 +1076,7 @@ static struct parm_struct parm_table[] = { {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED}, {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED}, {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED}, + {"ldap rebind sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_rebind_sleep, NULL, NULL, FLAG_ADVANCED}, {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR}, {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED}, @@ -1470,6 +1472,7 @@ static void init_globals(void) Globals.ldap_ssl = LDAP_SSL_ON; Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF; Globals.ldap_delete_dn = False; + Globals.ldap_rebind_sleep = 1000; /* wait 1 sec for replication */ /* these parameters are set to defaults that are more appropriate for the increasing samba install base: @@ -1701,6 +1704,7 @@ FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn) FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl) FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync) FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn) +FN_GLOBAL_INTEGER(lp_ldap_rebind_sleep, &Globals.ldap_rebind_sleep) FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand) FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand) FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand) -- cgit From 4205973b4315300860b512193b389fbb683cf3a0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 25 Dec 2003 23:35:27 +0000 Subject: (merge from 3.0) ldap rebind sleep -> ldap replication sleep While writing documentation for metze's patch, it became clear that this is a better name. Andrew Bartlett (This used to be commit bac2c20adf6a8f541f227652d4da3d8f31f1a648) --- source3/lib/smbldap.c | 2 +- source3/param/loadparm.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 9dca043584..944f60c689 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -926,7 +926,7 @@ int smbldap_search(struct smbldap_state *ldap_state, tdiff = 1000000 *(tval.tv_sec - ldap_state->last_rebind.tv_sec) + (tval.tv_usec - ldap_state->last_rebind.tv_usec); - sleep_time = ((1000*lp_ldap_rebind_sleep())-tdiff)/1000; + sleep_time = ((1000*lp_ldap_replication_sleep())-tdiff)/1000; if (sleep_time > 0) { /* we wait for the LDAP replication */ diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 1fbd54419c..67012ee087 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -235,7 +235,7 @@ typedef struct char *szLdapAdminDn; char *szAclCompat; int ldap_passwd_sync; - int ldap_rebind_sleep; + int ldap_replication_sleep; BOOL ldap_delete_dn; BOOL bMsAddPrinterWizard; BOOL bDNSproxy; @@ -1076,7 +1076,7 @@ static struct parm_struct parm_table[] = { {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED}, {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED}, {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED}, - {"ldap rebind sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_rebind_sleep, NULL, NULL, FLAG_ADVANCED}, + {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED}, {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR}, {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED}, @@ -1472,7 +1472,7 @@ static void init_globals(void) Globals.ldap_ssl = LDAP_SSL_ON; Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF; Globals.ldap_delete_dn = False; - Globals.ldap_rebind_sleep = 1000; /* wait 1 sec for replication */ + Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */ /* these parameters are set to defaults that are more appropriate for the increasing samba install base: @@ -1704,7 +1704,7 @@ FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn) FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl) FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync) FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn) -FN_GLOBAL_INTEGER(lp_ldap_rebind_sleep, &Globals.ldap_rebind_sleep) +FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep) FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand) FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand) FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand) -- cgit From 6af53b74840e3940546f9dd725b5cc072358885f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 26 Dec 2003 19:39:50 +0000 Subject: Collecting some minor patches... This adds the ability to specify the new user password for 'net ads password' on the command line. As this needs the admin password on the command line, the information leak is minimally more. Patch from gd@suse.de Volker (This used to be commit 68af56f517014476ab4549de72a0585a0a07c72f) --- source3/utils/net_ads.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 9404ae4b24..9ee2f3c093 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -44,9 +44,9 @@ int net_ads_usage(int argc, const char **argv) "\n\tdump the machine account details to stdout\n" "\nnet ads lookup"\ "\n\tperform a CLDAP search on the server\n" -"\nnet ads password -Uadmin_username@realm%%admin_pass"\ +"\nnet ads password -Uadmin_username@realm%%admin_pass"\ "\n\tchange a user's password using an admin account"\ -"\n\t(note: use realm in UPPERCASE)\n"\ +"\n\t(note: use realm in UPPERCASE, prompts if password is obmitted)\n"\ "\nnet ads changetrustpw"\ "\n\tchange the trust account password of this machine in the AD tree\n"\ "\nnet ads printer [info | publish | remove] "\ @@ -1016,7 +1016,7 @@ static int net_ads_password(int argc, const char **argv) } - if (argc != 1) { + if (argc < 1) { d_printf("ERROR: You must say which username to change password for\n"); return -1; } @@ -1048,22 +1048,24 @@ static int net_ads_password(int argc, const char **argv) return -1; } - asprintf(&prompt, "Enter new password for %s:", user); - - new_password = getpass(prompt); + if (argv[1]) { + new_password = (char *)argv[1]; + } else { + asprintf(&prompt, "Enter new password for %s:", user); + new_password = getpass(prompt); + free(prompt); + } ret = kerberos_set_password(ads->auth.kdc_server, auth_principal, auth_password, user, new_password, ads->auth.time_offset); if (!ADS_ERR_OK(ret)) { d_printf("Password change failed :-( ...\n"); ads_destroy(&ads); - free(prompt); return -1; } d_printf("Password change for %s completed.\n", user); ads_destroy(&ads); - free(prompt); return 0; } -- cgit From 67263790a0b66696677cff5aee43318db19d1657 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 26 Dec 2003 21:35:39 +0000 Subject: Collecting another little patch from gd@suse.de As broken as it might be, smbwrapper.so should be put into the libdir and not bindir. Volker (This used to be commit c374fd982e63209cf555fe8fbf15cfae0f79aca1) --- source3/smbwrapper/smbsh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbwrapper/smbsh.c b/source3/smbwrapper/smbsh.c index 221c6d87c2..7a2b8e09d7 100644 --- a/source3/smbwrapper/smbsh.c +++ b/source3/smbwrapper/smbsh.c @@ -36,7 +36,7 @@ static void smbsh_usage(void) int main(int argc, char *argv[]) { char *p, *u; - const char *libd = dyn_BINDIR; + const char *libd = dyn_LIBDIR; pstring line, wd; int opt; extern char *optarg; -- cgit From 889eb5ef5df9a50df09b04076efbc8d58bc3665e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 27 Dec 2003 10:13:20 +0000 Subject: Preliminary fix for our signing problem with failed NTLMSSP logins. This patch solves the problem for me here, I can still successfully set up signing using NTLMSSP against w2k3 and it does not show a signing error anymoe when the password was wrong. Jeremy, you might want to take a further look at it as this is not particularly elegant. Volker (This used to be commit 8a82060e3aee6d5ef38b1448035d865f9bce63a7) --- source3/libsmb/cliconnect.c | 22 +++++++++++++++------- source3/libsmb/smb_signing.c | 6 ++++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f6dfd40006..b140c772a2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -318,7 +318,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - cli_simple_set_signing(cli, session_key, nt_response); + cli_simple_set_signing(cli, session_key, nt_response, 0); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -511,7 +511,7 @@ static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *pr file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); #endif - cli_simple_set_signing(cli, session_key_krb5, null_blob); + cli_simple_set_signing(cli, session_key_krb5, null_blob, 0); blob2 = cli_session_setup_blob(cli, negTokenTarg); @@ -568,7 +568,6 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use blob_in, &blob_out); data_blob_free(&blob_in); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DATA_BLOB null_blob = data_blob(NULL, 0); if (turn == 1) { /* and wrap it in a SPNEGO wrapper */ msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); @@ -577,10 +576,6 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use msg1 = spnego_gen_auth(blob_out); } - cli_simple_set_signing(cli, - data_blob(ntlmssp_state->session_key.data, ntlmssp_state->session_key.length), - null_blob); - /* now send that blob on its way */ if (!cli_session_setup_blob_send(cli, msg1)) { DEBUG(3, ("Failed to send NTLMSSP/SPENGO blob to server!\n")); @@ -630,8 +625,21 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); if (NT_STATUS_IS_OK(nt_status)) { + + DATA_BLOB key = data_blob(ntlmssp_state->session_key.data, + ntlmssp_state->session_key.length); + DATA_BLOB null_blob = data_blob(NULL, 0); + fstrcpy(cli->server_domain, ntlmssp_state->server_domain); cli_set_session_key(cli, ntlmssp_state->session_key); + + /* Using NTLMSSP session setup, signing on the net only starts + * after a successful authentication and the session key has + * been determined, but with a sequence number of 2. This + * assumes that NTLMSSP needs exactly 2 roundtrips, for any + * other SPNEGO mechanism it needs adapting. */ + + cli_simple_set_signing(cli, key, null_blob, 2); } /* we have a reference conter on ntlmssp_state, if we are signing diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 6b2abb9ccc..8a056f659f 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -405,7 +405,9 @@ static void simple_free_signing_context(struct smb_sign_info *si) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response) +BOOL cli_simple_set_signing(struct cli_state *cli, + const DATA_BLOB user_session_key, + const DATA_BLOB response, int initial_send_seq_num) { struct smb_basic_signing_context *data; @@ -443,7 +445,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_ dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); /* Initialise the sequence number */ - data->send_seq_num = 0; + data->send_seq_num = initial_send_seq_num; /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; -- cgit From 1159b55c25fd7855491ea59576bfb8f8dc5c42e8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 30 Dec 2003 15:20:07 +0000 Subject: Fix Bug # 924 Volker (This used to be commit 1f0e045502f802f819738d1b89574b07dfaa6bc6) --- source3/torture/torture.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source3/torture/torture.c b/source3/torture/torture.c index d20c48d645..1fd73cb253 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -4577,12 +4577,14 @@ static BOOL run_test(const char *name) { BOOL ret = True; BOOL result = True; + BOOL found = False; int i; double t; if (strequal(name,"ALL")) { for (i=0;torture_ops[i].name;i++) { run_test(torture_ops[i].name); } + found = True; } for (i=0;torture_ops[i].name;i++) { @@ -4590,6 +4592,7 @@ static BOOL run_test(const char *name) (unsigned)random()); if (strequal(name, torture_ops[i].name)) { + found = True; printf("Running %s\n", name); if (torture_ops[i].flags & FLAG_MULTIPROC) { t = create_procs(torture_ops[i].fn, &result); @@ -4609,6 +4612,12 @@ static BOOL run_test(const char *name) printf("%s took %g secs\n\n", name, t); } } + + if (!found) { + printf("Did not find a test named %s\n", name); + ret = False; + } + return ret; } @@ -4776,10 +4785,10 @@ static void usage(void) printf("host=%s share=%s user=%s myname=%s\n", host, share, username, myname); - if (argc == 1) { + if (argc == optind) { correct = run_test("ALL"); } else { - for (i=1;i Date: Tue, 30 Dec 2003 16:01:24 +0000 Subject: The AFS pts command always generates completely lower-case user names. As case is not significant in windows user names we should not lose information by lower-casing the name before handing it to AFS. Volker (This used to be commit 097e8d44b4a6eb49f36debae1f2cc8af7565b0eb) --- source3/lib/afs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/lib/afs.c b/source3/lib/afs.c index fc78950f39..789afcdd83 100644 --- a/source3/lib/afs.c +++ b/source3/lib/afs.c @@ -142,6 +142,10 @@ BOOL afs_login(connection_struct *conn) pstrcpy(afs_username, lp_afs_username_map()); standard_sub_conn(conn, afs_username, sizeof(afs_username)); + /* The pts command always generates completely lower-case user + * names. */ + strlower_m(afs_username); + cell = strchr(afs_username, '@'); if (cell == NULL) { @@ -152,7 +156,6 @@ BOOL afs_login(connection_struct *conn) *cell = '\0'; cell += 1; - strlower_m(cell); DEBUG(10, ("Trying to log into AFS for user %s@%s\n", afs_username, cell)); -- cgit From 65586823a743bc7585e4703ddab35e16f2007e95 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 30 Dec 2003 21:12:57 +0000 Subject: Another little one: Make pdb_test.c at least compile, although its way out of date. Volker (This used to be commit 0a84173555b29b77b241741c7b1ae4fac595c28f) --- examples/pdb/Makefile | 2 +- examples/pdb/pdb_test.c | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/examples/pdb/Makefile b/examples/pdb/Makefile index 115fd3c87e..a53cd5d5e2 100644 --- a/examples/pdb/Makefile +++ b/examples/pdb/Makefile @@ -8,7 +8,7 @@ SAMBA_SRC = ../../source SAMBA_INCL = ../../source/include UBIQX_SRC = ../../source/ubiqx SMBWR_SRC = ../../source/smbwrapper -CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g +CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g -I/usr/include/heimdal -fPIC PDB_OBJS = pdb_test.so # Default target diff --git a/examples/pdb/pdb_test.c b/examples/pdb/pdb_test.c index f5fb57ddb2..e46c621d48 100644 --- a/examples/pdb/pdb_test.c +++ b/examples/pdb/pdb_test.c @@ -139,11 +139,7 @@ NTSTATUS testsam_init(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const return NT_STATUS_OK; } -int init_module(void); - -int init_module() { - if(smb_register_passdb("testsam", testsam_init, PASSDB_INTERFACE_VERSION)) - return 0; - - return 1; +NTSTATUS init_module(void) { + return smb_register_passdb(PASSDB_INTERFACE_VERSION, "testsam", + testsam_init); } -- cgit From 6eb471e11e596bc27d2d42ff457d6bd772eed228 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 30 Dec 2003 22:18:40 +0000 Subject: Move to short lived TALLOC_CTX* for allocating printer objects from the print handle cache. Fixes bug that caused smbd to consume large amounts of RAM when (a) a printer handle was kept open over an extended period of time, and (b) the client issued frequent requests that resulted in a call to get_a_printer() (This used to be commit b84ea23f99481f9260dedbe8dd715112ccdc7d7a) --- source3/printing/nt_printing.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index f3c3a0389a..7ba777f131 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -3920,6 +3920,16 @@ NT_PRINTER_INFO_LEVEL_2* dup_printer_2( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 /**************************************************************************** Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory. + + Previously the code had a memory allocation problem because it always + used the TALLOC_CTX from the Printer_entry*. This context lasts + as a long as the original handle is open. So if the client made a lot + of getprinter[data]() calls, the memory usage would climb. Now we use + a short lived TALLOC_CTX for printer_info_2 objects returned. We + still use the Printer_entry->ctx for maintaining the cache copy though + since that object must live as long as the handle by definition. + --jerry + ****************************************************************************/ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, @@ -3950,7 +3960,11 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER) && print_hnd->printer_info ) { - if ( !(printer->info_2 = dup_printer_2(print_hnd->ctx, print_hnd->printer_info->info_2)) ) { + /* get_talloc_ctx() works here because we need a short + lived talloc context */ + + if ( !(printer->info_2 = dup_printer_2(get_talloc_ctx(), print_hnd->printer_info->info_2)) ) + { DEBUG(0,("get_a_printer: unable to copy cached printer info!\n")); SAFE_FREE(printer); @@ -3965,10 +3979,11 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print break; } - /* no cache for this handle; see if we can match one from another handle */ - + /* no cache for this handle; see if we can match one from another handle. + Make sure to use a short lived talloc ctx */ + if ( print_hnd ) - result = find_printer_in_print_hnd_cache(print_hnd->ctx, &printer->info_2, sharename); + result = find_printer_in_print_hnd_cache(get_talloc_ctx(), &printer->info_2, sharename); /* fail to disk if we don't have it with any open handle */ @@ -3986,6 +4001,9 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print print_hnd->printer_info = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL)); if ( print_hnd->printer_info ) { + /* make sure to use the handle's talloc ctx here since + the printer_2 object must last until the handle is closed */ + print_hnd->printer_info->info_2 = dup_printer_2(print_hnd->ctx, printer->info_2); /* don't fail the lookup just because the cache update failed */ -- cgit From 1c13660eebdc905c2df819aa273737c179452957 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 1 Jan 2004 20:33:45 +0000 Subject: Fix for bug 707, getent group for huge ads groups (>1500 members) This introduces range retrieval of ADS attributes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I've rewritten most of Günther's patch, partly to remove code duplication and partly to get the retrieval of members in one rush, not interrupted by the lookups for the DN. Andrew, you told me that you would like to see a check whether the AD sequence number is the same before and after the retrieval to achieve atomicity. This would be trivial to add, but I'm not sure that we want this, as this adds two roundtrips to every membership query. We can not know before the first query whether we get additional range values, and at that point it's too late to ask for the USN. Tested with a group of 4000 members along with lots of small groups. Volker (This used to be commit a2aa6e41e552abfb6d1056ab3a7c75e8fd0a150c) --- source3/libads/ldap.c | 100 ++++++++++++++++++++++++++++++++++++---- source3/nsswitch/winbindd_ads.c | 69 ++++++++++++++++++--------- 2 files changed, 140 insertions(+), 29 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6e40089b70..19b4ed475c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1573,27 +1573,26 @@ char *ads_pull_string(ADS_STRUCT *ads, * @return Result strings in talloc context **/ char **ads_pull_strings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field) + TALLOC_CTX *mem_ctx, void *msg, const char *field, + int *num_values) { char **values; char **ret = NULL; - int i, n; + int i; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; - for (i=0;values[i];i++) - /* noop */ ; - n = i; + *num_values = ldap_count_values(values); - ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); if (!ret) { ldap_value_free(values); return NULL; } - for (i=0;ild, (LDAPMessage *)msg, &ptr); + + if (first_attr == NULL) + return NULL; + + expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field); + + if (!strequal(first_attr, field) && + !strnequal(first_attr, expected_range_attrib, + strlen(expected_range_attrib))) + { + DEBUG(1, ("Expected attribute [%s], got [%s]\n", + field, first_attr)); + return NULL; + } + + second_attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr); + ber_free(ptr, 0); + + DEBUG(10,("attr: [%s], first_attr: [%s], second_attr: [%s]\n", + field, first_attr, second_attr)); + + if ((second_attr != NULL) && + (strnequal(second_attr, expected_range_attrib, + strlen(expected_range_attrib)))) { + + /* This is the first in a row of range results. We can not ask + * for the attribute we wanted, as this is empty in the LDAP + * msg, the delivered values are in the second range-augmented + * attribute. */ + range_attr = second_attr; + + } else { + + /* Upon second and subsequent requests to get attribute + * values, first_attr carries the Range= specifier. */ + range_attr = first_attr; + + } + + /* We have to ask for more if we have a range specifier in the + * attribute and the attribute does not end in "*". */ + + *more_values = ( (strnequal(range_attr, expected_range_attrib, + strlen(expected_range_attrib))) && + (range_attr[strlen(range_attr)-1] != '*') ); + + result = ads_pull_strings(ads, mem_ctx, msg, range_attr, num_values); + + ldap_memfree(first_attr); + if (second_attr != NULL) + ldap_memfree(second_attr); + + return result; +} /** * pull a single uint32 from a ADS result @@ -1956,6 +2038,7 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * int i; void *res; const char *attrs[] = {"servicePrincipalName", NULL}; + int num_principals; (*workgroup) = NULL; @@ -1968,7 +2051,8 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * return rc; } - principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName"); + principles = ads_pull_strings(ads, mem_ctx, res, + "servicePrincipalName", &num_principals); ads_msgfree(ads, res); diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 5d0f924d8f..11767504c1 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -689,10 +689,11 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, char *ldap_exp; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; char *sidstr; - const char *attrs[] = {"member", NULL}; char **members; int i, num_members; fstring sid_string; + const char *attr = "member"; + BOOL more_values; DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, sid_string_static(group_sid))); @@ -709,33 +710,56 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, /* search for all members of the group */ asprintf(&ldap_exp, "(objectSid=%s)",sidstr); - rc = ads_search_retry(ads, &res, ldap_exp, attrs); - free(ldap_exp); - free(sidstr); - if (!ADS_ERR_OK(rc) || !res) { - DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc))); - goto done; - } + members = NULL; + num_members = 0; + more_values = True; - count = ads_count_replies(ads, res); - if (count == 0) { - status = NT_STATUS_OK; - goto done; - } + while (more_values) { - members = ads_pull_strings(ads, mem_ctx, res, "member"); - if (!members) { - /* no members? ok ... */ - status = NT_STATUS_OK; - goto done; - } + int num_this_time; + char **new_members; + const char *attrs[] = {attr, NULL}; + + rc = ads_search_retry(ads, &res, ldap_exp, attrs); + if (!ADS_ERR_OK(rc) || !res) { + DEBUG(1,("query_user_list ads_search: %s\n", + ads_errstr(rc))); + goto done; + } + + count = ads_count_replies(ads, res); + if (count == 0) + break; + + new_members = ads_pull_strings_range(ads, mem_ctx, res, + "member", + &num_this_time, + &more_values); + + if ((new_members == NULL) || (num_this_time == 0)) + break; + + members = talloc_realloc(mem_ctx, members, + sizeof(*members) * + (num_members+num_this_time)); + + if (members == NULL) + break; + + memcpy(members+num_members, new_members, + sizeof(new_members)*num_this_time); + + num_members += num_this_time; + + attr = talloc_asprintf(mem_ctx, + "member;range=%d-*", num_members); + } + /* now we need to turn a list of members into rids, names and name types the problem is that the members are in the form of distinguised names */ - for (i=0;members[i];i++) /* noop */ ; - num_members = i; (*sid_mem) = talloc_zero(mem_ctx, sizeof(**sid_mem) * num_members); (*name_types) = talloc_zero(mem_ctx, sizeof(**name_types) * num_members); @@ -762,6 +786,9 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, status = NT_STATUS_OK; DEBUG(3,("ads lookup_groupmem for sid=%s\n", sid_to_string(sid_string, group_sid))); done: + SAFE_FREE(ldap_exp); + SAFE_FREE(sidstr); + if (res) ads_msgfree(ads, res); -- cgit From c6f6cad41f9ce2d1691e7ca18f7c1d50764e61e5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 1 Jan 2004 21:11:33 +0000 Subject: After talking with abartlet remove the fix for bug 707 again. Volker (This used to be commit a2e384262d0203772a6237b566c294f15bfd8948) --- source3/libads/ldap.c | 100 ++++------------------------------------ source3/nsswitch/winbindd_ads.c | 69 +++++++++------------------ 2 files changed, 29 insertions(+), 140 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 19b4ed475c..6e40089b70 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1573,26 +1573,27 @@ char *ads_pull_string(ADS_STRUCT *ads, * @return Result strings in talloc context **/ char **ads_pull_strings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field, - int *num_values) + TALLOC_CTX *mem_ctx, void *msg, const char *field) { char **values; char **ret = NULL; - int i; + int i, n; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; - *num_values = ldap_count_values(values); + for (i=0;values[i];i++) + /* noop */ ; + n = i; - ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); + ret = talloc(mem_ctx, sizeof(char *) * (n+1)); if (!ret) { ldap_value_free(values); return NULL; } - for (i=0;i<*num_values;i++) { + for (i=0;ild, (LDAPMessage *)msg, &ptr); - - if (first_attr == NULL) - return NULL; - - expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field); - - if (!strequal(first_attr, field) && - !strnequal(first_attr, expected_range_attrib, - strlen(expected_range_attrib))) - { - DEBUG(1, ("Expected attribute [%s], got [%s]\n", - field, first_attr)); - return NULL; - } - - second_attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr); - ber_free(ptr, 0); - - DEBUG(10,("attr: [%s], first_attr: [%s], second_attr: [%s]\n", - field, first_attr, second_attr)); - - if ((second_attr != NULL) && - (strnequal(second_attr, expected_range_attrib, - strlen(expected_range_attrib)))) { - - /* This is the first in a row of range results. We can not ask - * for the attribute we wanted, as this is empty in the LDAP - * msg, the delivered values are in the second range-augmented - * attribute. */ - range_attr = second_attr; - - } else { - - /* Upon second and subsequent requests to get attribute - * values, first_attr carries the Range= specifier. */ - range_attr = first_attr; - - } - - /* We have to ask for more if we have a range specifier in the - * attribute and the attribute does not end in "*". */ - - *more_values = ( (strnequal(range_attr, expected_range_attrib, - strlen(expected_range_attrib))) && - (range_attr[strlen(range_attr)-1] != '*') ); - - result = ads_pull_strings(ads, mem_ctx, msg, range_attr, num_values); - - ldap_memfree(first_attr); - if (second_attr != NULL) - ldap_memfree(second_attr); - - return result; -} /** * pull a single uint32 from a ADS result @@ -2038,7 +1956,6 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * int i; void *res; const char *attrs[] = {"servicePrincipalName", NULL}; - int num_principals; (*workgroup) = NULL; @@ -2051,8 +1968,7 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * return rc; } - principles = ads_pull_strings(ads, mem_ctx, res, - "servicePrincipalName", &num_principals); + principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName"); ads_msgfree(ads, res); diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 11767504c1..5d0f924d8f 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -689,11 +689,10 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, char *ldap_exp; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; char *sidstr; + const char *attrs[] = {"member", NULL}; char **members; int i, num_members; fstring sid_string; - const char *attr = "member"; - BOOL more_values; DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, sid_string_static(group_sid))); @@ -710,56 +709,33 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, /* search for all members of the group */ asprintf(&ldap_exp, "(objectSid=%s)",sidstr); + rc = ads_search_retry(ads, &res, ldap_exp, attrs); + free(ldap_exp); + free(sidstr); - members = NULL; - num_members = 0; - more_values = True; - - while (more_values) { - - int num_this_time; - char **new_members; - const char *attrs[] = {attr, NULL}; - - rc = ads_search_retry(ads, &res, ldap_exp, attrs); - - if (!ADS_ERR_OK(rc) || !res) { - DEBUG(1,("query_user_list ads_search: %s\n", - ads_errstr(rc))); - goto done; - } - - count = ads_count_replies(ads, res); - if (count == 0) - break; - - new_members = ads_pull_strings_range(ads, mem_ctx, res, - "member", - &num_this_time, - &more_values); - - if ((new_members == NULL) || (num_this_time == 0)) - break; - - members = talloc_realloc(mem_ctx, members, - sizeof(*members) * - (num_members+num_this_time)); - - if (members == NULL) - break; - - memcpy(members+num_members, new_members, - sizeof(new_members)*num_this_time); + if (!ADS_ERR_OK(rc) || !res) { + DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc))); + goto done; + } - num_members += num_this_time; + count = ads_count_replies(ads, res); + if (count == 0) { + status = NT_STATUS_OK; + goto done; + } - attr = talloc_asprintf(mem_ctx, - "member;range=%d-*", num_members); + members = ads_pull_strings(ads, mem_ctx, res, "member"); + if (!members) { + /* no members? ok ... */ + status = NT_STATUS_OK; + goto done; } - + /* now we need to turn a list of members into rids, names and name types the problem is that the members are in the form of distinguised names */ + for (i=0;members[i];i++) /* noop */ ; + num_members = i; (*sid_mem) = talloc_zero(mem_ctx, sizeof(**sid_mem) * num_members); (*name_types) = talloc_zero(mem_ctx, sizeof(**name_types) * num_members); @@ -786,9 +762,6 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, status = NT_STATUS_OK; DEBUG(3,("ads lookup_groupmem for sid=%s\n", sid_to_string(sid_string, group_sid))); done: - SAFE_FREE(ldap_exp); - SAFE_FREE(sidstr); - if (res) ads_msgfree(ads, res); -- cgit From 60639680195015739909ea7a2be032bdbab4f76c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 3 Jan 2004 20:21:37 +0000 Subject: And yet another const Volker (This used to be commit 6121a866659c3b81e790a79432b6d89d7865fbd3) --- source3/nsswitch/winbindd_ads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 5d0f924d8f..f12aee4112 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -933,7 +933,7 @@ static NTSTATUS alternate_name(struct winbindd_domain *domain) ADS_STRUCT *ads; ADS_STATUS rc; TALLOC_CTX *ctx; - char *workgroup; + const char *workgroup; DEBUG(3,("ads: alternate_name\n")); -- cgit From 612a97f84535c2d2b397f7a1b3941f7f6f602b27 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 4 Jan 2004 11:59:11 +0000 Subject: Commit the translation of the realm to the netbios domain name in the kerberos session setup. After talking to jht and abartlet I made this unconditional, no additional parameter. Jerry: This is a change in behaviour, but I think it is necessary. Volker (This used to be commit d32f47fedcff3fdf46f42926d1cd84433e7ab487) --- source3/nsswitch/wbinfo.c | 44 ++++++++++++++++++++++++++++++++++++++++ source3/nsswitch/winbindd.c | 1 + source3/nsswitch/winbindd_misc.c | 29 ++++++++++++++++++++++++++ source3/nsswitch/winbindd_nss.h | 11 ++++++++++ source3/smbd/sesssetup.c | 44 +++++++++++++++++++++++++++++++++++++--- 5 files changed, 126 insertions(+), 3 deletions(-) diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 04233bb85c..bca1813167 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -247,6 +247,42 @@ static BOOL wbinfo_show_sequence(const char *domain) return True; } +/* Show domain info */ + +static BOOL wbinfo_domain_info(const char *domain_name) +{ + struct winbindd_request request; + struct winbindd_response response; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + fstrcpy(request.domain_name, domain_name); + + /* Send request */ + + if (winbindd_request(WINBINDD_DOMAIN_INFO, &request, &response) != + NSS_STATUS_SUCCESS) + return False; + + /* Display response */ + + d_printf("Name : %s\n", response.data.domain_info.name); + d_printf("Alt_Name: %s\n", response.data.domain_info.alt_name); + + d_printf("SID : %s\n", response.data.domain_info.sid); + + d_printf("Native : %s\n", + response.data.domain_info.native_mode ? "Yes" : "No"); + + d_printf("Primary : %s\n", + response.data.domain_info.primary ? "Yes" : "No"); + + d_printf("Sequence: %d\n", response.data.domain_info.sequence_number); + + return True; +} + /* Check trust account password */ static BOOL wbinfo_check_secret(void) @@ -922,6 +958,8 @@ int main(int argc, char **argv) { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" }, { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" }, { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" }, + { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', + "Show all most info we have about the domain" }, { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" }, { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" }, { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" }, @@ -1048,6 +1086,12 @@ int main(int argc, char **argv) goto done; } break; + case 'D': + if (!wbinfo_domain_info(string_arg)) { + d_printf("Could not get domain info\n"); + goto done; + } + break; case 'r': if (!wbinfo_get_usergroups(string_arg)) { d_printf("Could not get groups for user %s\n", diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 4b47ac13a2..b1c0c67d52 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -262,6 +262,7 @@ static struct dispatch_table dispatch_table[] = { { WINBINDD_INFO, winbindd_info, "INFO" }, { WINBINDD_INTERFACE_VERSION, winbindd_interface_version, "INTERFACE_VERSION" }, { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" }, + { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" }, { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" }, { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir, "WINBINDD_PRIV_PIPE_DIR" }, diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c index 88fbb5ee00..1a5ecb56c7 100644 --- a/source3/nsswitch/winbindd_misc.c +++ b/source3/nsswitch/winbindd_misc.c @@ -202,6 +202,35 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state) return WINBINDD_OK; } +enum winbindd_result winbindd_domain_info(struct winbindd_cli_state *state) +{ + struct winbindd_domain *domain; + + DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)state->pid, + state->request.domain_name)); + + domain = find_domain_from_name(state->request.domain_name); + + if (domain == NULL) { + DEBUG(3, ("Did not find domain [%s]\n", + state->request.domain_name)); + return WINBINDD_ERROR; + } + + fstrcpy(state->response.data.domain_info.name, domain->name); + fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name); + fstrcpy(state->response.data.domain_info.sid, + sid_string_static(&domain->sid)); + + state->response.data.domain_info.native_mode = domain->native_mode; + state->response.data.domain_info.primary = domain->primary; + + state->response.data.domain_info.sequence_number = + domain->sequence_number; + + return WINBINDD_OK; +} + enum winbindd_result winbindd_ping(struct winbindd_cli_state *state) { diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index 41fecd2816..00d49e7d3e 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -92,6 +92,9 @@ enum winbindd_cmd { WINBINDD_INFO, /* Various bit of info. Currently just tidbits */ WINBINDD_DOMAIN_NAME, /* The domain this winbind server is a member of (lp_workgroup()) */ + WINBINDD_DOMAIN_INFO, /* Most of what we know from + struct winbindd_domain */ + WINBINDD_SHOW_SEQUENCE, /* display sequence numbers of domains */ /* WINS commands */ @@ -260,6 +263,14 @@ struct winbindd_response { char first_8_lm_hash[8]; } auth; uint32 rid; /* create user or group */ + struct { + fstring name; + fstring alt_name; + fstring sid; + BOOL native_mode; + BOOL primary; + uint32 sequence_number; + } domain_info; } data; /* Variable length return data */ diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e9cfa47d0c..2c38cd3eb3 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -141,7 +141,8 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB *secblob) { DATA_BLOB ticket; - char *client, *p; + char *client, *p, *domain; + fstring netbios_domain_name; const struct passwd *pw; char *user; int sess_vuid; @@ -198,8 +199,45 @@ static int reply_spnego_kerberos(connection_struct *conn, /* this gives a fully qualified user name (ie. with full realm). that leads to very long usernames, but what else can we do? */ - - asprintf(&user, "%s%c%s", p+1, *lp_winbind_separator(), client); + + domain = p+1; + + { + /* If we have winbind running, we can (and must) shorten the + username by using the short netbios name. Otherwise we will + have inconsistent user names. With Kerberos, we get the + fully qualified realm, with ntlmssp we get the short + name. And even w2k3 does use ntlmssp if you for example + connect to an ip address. */ + + struct winbindd_request wb_request; + struct winbindd_response wb_response; + NSS_STATUS wb_result; + + ZERO_STRUCT(wb_request); + ZERO_STRUCT(wb_response); + + DEBUG(10, ("Mapping [%s] to short name\n", domain)); + + fstrcpy(wb_request.domain_name, domain); + + wb_result = winbindd_request(WINBINDD_DOMAIN_INFO, + &wb_request, &wb_response); + + if (wb_result == NSS_STATUS_SUCCESS) { + + fstrcpy(netbios_domain_name, + wb_response.data.domain_info.name); + domain = netbios_domain_name; + + DEBUG(10, ("Mapped to [%s]\n", domain)); + } else { + DEBUG(3, ("Could not find short name -- winbind " + "not running?\n")); + } + } + + asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client); pw = smb_getpwnam( user ); -- cgit From b397269f1b981df735bb98eec94adb142de0a868 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 5 Jan 2004 00:57:53 +0000 Subject: Merge commit to 3_0: add pdb_pgsql (This used to be commit 61cbd5c9be1962d0c33c28ff472a2f82d3aa2a80) --- source3/Makefile.in | 8 +- source3/aclocal.m4 | 45 ++++ source3/configure.in | 17 +- source3/include/passdb.h | 2 + source3/passdb/pdb_mysql.c | 524 ++------------------------------------------- source3/passdb/pdb_pgsql.c | 489 ++++++++++++++++++++++++++++++++++++++++++ source3/passdb/pdb_sql.c | 496 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 1074 insertions(+), 507 deletions(-) create mode 100644 source3/passdb/pdb_pgsql.c create mode 100644 source3/passdb/pdb_sql.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 63dfeeec5f..042f424861 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -294,10 +294,11 @@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ passdb/machine_sid.o passdb/util_sam_sid.o passdb/pdb_compat.o \ passdb/privileges.o passdb/lookup_sid.o @PDB_STATIC@ \ - $(GUMS_OBJ) @GUMS_STATIC@ + $(GUMS_OBJ) @GUMS_STATIC@ passdb/pdb_sql.o XML_OBJ = passdb/pdb_xml.o MYSQL_OBJ = passdb/pdb_mysql.o +PGSQL_OBJ = passdb/pdb_pgsql.o DEVEL_HELP_WEIRD_OBJ = modules/weird.o CP850_OBJ = modules/CP850.o CP437_OBJ = modules/CP437.o @@ -1085,6 +1086,11 @@ bin/mysql.@SHLIBEXT@: $(MYSQL_OBJ:.o=.@PICSUFFIX@) @$(SHLD) $(LDSHFLAGS) -o $@ $(MYSQL_OBJ:.o=.@PICSUFFIX@) @MYSQL_LIBS@ \ @SONAMEFLAG@`basename $@` +bin/pgsql.@SHLIBEXT@: $(PGSQL_OBJ:.o=.po) + @echo "Building plugin $@" + @$(SHLD) $(LDSHFLAGS) -o $@ $(PGSQL_OBJ:.o=.po) @PGSQL_LIBS@ \ + @SONAMEFLAG@`basename $@` + bin/ldapsam.@SHLIBEXT@: passdb/pdb_ldap.@PICSUFFIX@ @echo "Building plugin $@" @$(SHLD) $(LDSHFLAGS) $(LDAP_LIBS) -o $@ passdb/pdb_ldap.@PICSUFFIX@ \ diff --git a/source3/aclocal.m4 b/source3/aclocal.m4 index 96f265daf2..6de11953b4 100644 --- a/source3/aclocal.m4 +++ b/source3/aclocal.m4 @@ -484,6 +484,51 @@ AC_ARG_WITH(mysql-exec-prefix,[ --with-mysql-exec-prefix=PFX Exec prefix where AC_SUBST(MYSQL_LIBS) ]) +# ========================================================================= +# AM_PATH_PGSQL : pgSQL library + +dnl AM_PATH_PGSQL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for PGSQL, and define PGSQL_CFLAGS and PGSQL_LIBS +dnl +AC_DEFUN(AM_PATH_PGSQL, +[dnl +dnl Get the cflags and libraries from the pg_config script +dnl +AC_ARG_WITH(pgsql-prefix,[ --with-pgsql-prefix=PFX Prefix where PostgreSQL is installed (optional)], + pgsql_prefix="$withval", pgsql_prefix="") +AC_ARG_WITH(pgsql-exec-prefix,[ --with-pgsql-exec-prefix=PFX Exec prefix where PostgreSQL is installed (optional)], + pgsql_exec_prefix="$withval", pgsql_exec_prefix="") + + if test x$pgsql_exec_prefix != x ; then + if test x${PGSQL_CONFIG+set} != xset ; then + PGSQL_CONFIG=$pgsql_exec_prefix/bin/pg_config + fi + fi + if test x$pgsql_prefix != x ; then + if test x${PGSQL_CONFIG+set} != xset ; then + PGSQL_CONFIG=$pgsql_prefix/bin/pg_config + fi + fi + + AC_REQUIRE([AC_CANONICAL_TARGET]) + AC_PATH_PROG(PGSQL_CONFIG, pg_config, no, [$PATH:/usr/lib/postgresql/bin]) + AC_MSG_CHECKING(for PGSQL) + no_pgsql="" + if test "$PGSQL_CONFIG" = "no" ; then + PGSQL_CFLAGS="" + PGSQL_LIBS="" + AC_MSG_RESULT(no) + ifelse([$2], , :, [$2]) + else + PGSQL_CFLAGS=-I`$PGSQL_CONFIG --includedir` + PGSQL_LIBS="-lpq -L`$PGSQL_CONFIG --libdir`" + AC_MSG_RESULT(yes) + ifelse([$1], , :, [$1]) + fi + AC_SUBST(PGSQL_CFLAGS) + AC_SUBST(PGSQL_LIBS) +]) + dnl Removes -I/usr/include/? from given variable AC_DEFUN(CFLAGS_REMOVE_USR_INCLUDE,[ ac_new_flags="" diff --git a/source3/configure.in b/source3/configure.in index c692569e36..9b87aa6296 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2760,30 +2760,35 @@ fi ######################################################## # Compile experimental passdb backends? -# (pdb_xml, pdb_mysql) +# (pdb_xml, pdb_mysql, pdb_pgsql) AC_MSG_CHECKING(whether to build experimental passdb libraries) AC_ARG_WITH(expsam, [ --with-expsam= Include experimental passdb libraries (default=no)] [ Valid choices include (comma separated list): ] -[ xml & mysql], +[ xml, mysql & pgsql], [ expsam_pdb_modules=`echo "$withval" | sed 's/,/ /g'` if test "z$expsam_pdb_modules" = "zyes"; then - expsam_pdb_modules="xml mysql" + expsam_pdb_modules="xml mysql pgsql" fi AC_MSG_RESULT($expsam_pdb_modules) for i in $expsam_pdb_modules do case "$i" in - xml) + xml|all|yes) ## pdb_xml AM_PATH_XML2([2.0.0],[default_shared_modules="$default_shared_modules pdb_xml"],[AC_MSG_ERROR([Can't find XML libraries while XML support is requested])]) CFLAGS="$CFLAGS $XML_CFLAGS" ;; - mysql) + mysql|all|yes) ## pdb_mysql AM_PATH_MYSQL([default_shared_modules="$default_shared_modules pdb_mysql"],[AC_MSG_ERROR([Can't find MySQL libraries while MySQL support is requested])]) CFLAGS="$CFLAGS $MYSQL_CFLAGS" ;; + pgsql|all|yes) + ## pdb_pgsql + AM_PATH_PGSQL([default_shared_modules="$default_shared_modules pdb_pgsql"],[]) + CFLAGS="$CFLAGS $PGSQL_CFLAGS" + ;; no) ;; *) @@ -4180,6 +4185,8 @@ SMB_MODULE(pdb_xml, passdb/pdb_xml.o, "bin/xml.$SHLIBEXT", PDB, [ PASSDB_LIBS="$PASSDB_LIBS $XML_LIBS" ] ) SMB_MODULE(pdb_mysql, passdb/pdb_mysql.o, "bin/mysql.$SHLIBEXT", PDB, [ PASSDB_LIBS="$PASSDB_LIBS $MYSQL_LIBS" ] ) +SMB_MODULE(pdb_pgsql, passdb/pdb_pgsql.o, "bin/pgsql.$SHLIBEXT", PDB, + [ PASSDB_LIBS="$PASSDB_LIBS $PGSQL_LIBS" ] ) ## end of contributed pdb_modules ########################################################################### diff --git a/source3/include/passdb.h b/source3/include/passdb.h index be1f236e39..d7f11781fe 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -361,4 +361,6 @@ struct pdb_init_function_entry { struct pdb_init_function_entry *prev, *next; }; +enum sql_search_field { SQL_SEARCH_NONE = 0, SQL_SEARCH_USER_SID = 1, SQL_SEARCH_USER_NAME = 2}; + #endif /* _PASSDB_H */ diff --git a/source3/passdb/pdb_mysql.c b/source3/passdb/pdb_mysql.c index 7c2c56e359..acc1eff829 100644 --- a/source3/passdb/pdb_mysql.c +++ b/source3/passdb/pdb_mysql.c @@ -1,7 +1,6 @@ - /* * MySQL password backend for samba - * Copyright (C) Jelmer Vernooij 2002 + * Copyright (C) Jelmer Vernooij 2002-2004 * * 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 the Free @@ -21,37 +20,6 @@ #include "includes.h" #include -#define CONFIG_TABLE_DEFAULT "user" -#define CONFIG_LOGON_TIME_DEFAULT "logon_time" -#define CONFIG_LOGOFF_TIME_DEFAULT "logoff_time" -#define CONFIG_KICKOFF_TIME_DEFAULT "kickoff_time" -#define CONFIG_PASS_LAST_SET_TIME_DEFAULT "pass_last_set_time" -#define CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT "pass_can_change_time" -#define CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT "pass_must_change_time" -#define CONFIG_USERNAME_DEFAULT "username" -#define CONFIG_DOMAIN_DEFAULT "domain" -#define CONFIG_NT_USERNAME_DEFAULT "nt_username" -#define CONFIG_FULLNAME_DEFAULT "nt_fullname" -#define CONFIG_HOME_DIR_DEFAULT "home_dir" -#define CONFIG_DIR_DRIVE_DEFAULT "dir_drive" -#define CONFIG_LOGON_SCRIPT_DEFAULT "logon_script" -#define CONFIG_PROFILE_PATH_DEFAULT "profile_path" -#define CONFIG_ACCT_DESC_DEFAULT "acct_desc" -#define CONFIG_WORKSTATIONS_DEFAULT "workstations" -#define CONFIG_UNKNOWN_STR_DEFAULT "unknown_str" -#define CONFIG_MUNGED_DIAL_DEFAULT "munged_dial" -#define CONFIG_USER_SID_DEFAULT "user_sid" -#define CONFIG_GROUP_SID_DEFAULT "group_sid" -#define CONFIG_LM_PW_DEFAULT "lm_pw" -#define CONFIG_NT_PW_DEFAULT "nt_pw" -#define CONFIG_PLAIN_PW_DEFAULT "NULL" -#define CONFIG_ACCT_CTRL_DEFAULT "acct_ctrl" -#define CONFIG_UNKNOWN_3_DEFAULT "unknown_3" -#define CONFIG_LOGON_DIVS_DEFAULT "logon_divs" -#define CONFIG_HOURS_LEN_DEFAULT "hours_len" -#define CONFIG_BAD_PASSWORD_COUNT_DEFAULT "bad_password_count" -#define CONFIG_LOGON_COUNT_DEFAULT "logon_count" -#define CONFIG_UNKNOWN_6_DEFAULT "unknown_6" #define CONFIG_HOST_DEFAULT "localhost" #define CONFIG_USER_DEFAULT "samba" #define CONFIG_PASS_DEFAULT "" @@ -69,14 +37,6 @@ typedef struct pdb_mysql_data { const char *location; } pdb_mysql_data; -/* Used to construct insert and update queries */ - -typedef struct pdb_mysql_query { - char update; - TALLOC_CTX *mem_ctx; - char *part1; - char *part2; -} pdb_mysql_query; #define SET_DATA(data,methods) { \ if(!methods){ \ DEBUG(0, ("invalid methods!\n")); \ @@ -89,125 +49,13 @@ typedef struct pdb_mysql_query { } \ } -static void pdb_mysql_int_field(struct pdb_methods *m, - struct pdb_mysql_query *q, const char *name, int value) -{ - if (!name || strchr(name, '\'')) - return; /* This field shouldn't be set by us */ - - if (q->update) { - q->part1 = - talloc_asprintf_append(q->mem_ctx, q->part1, - "%s = %d,", name, value); - } else { - q->part1 = - talloc_asprintf_append(q->mem_ctx, q->part1, "%s,", name); - q->part2 = - talloc_asprintf_append(q->mem_ctx, q->part2, "%d,", value); - } -} - -static NTSTATUS pdb_mysql_string_field(struct pdb_methods *methods, - struct pdb_mysql_query *q, - const char *name, const char *value) -{ - char *esc_value; - struct pdb_mysql_data *data; - char *tmp_value; - - SET_DATA(data, methods); - - if (!name || !value || !strcmp(value, "") || strchr(name, '\'')) - return NT_STATUS_INVALID_PARAMETER; /* This field shouldn't be set by module */ - - esc_value = malloc(strlen(value) * 2 + 1); - - tmp_value = smb_xstrdup(value); - mysql_real_escape_string(data->handle, esc_value, tmp_value, - strlen(tmp_value)); - SAFE_FREE(tmp_value); - - if (q->update) { - q->part1 = - talloc_asprintf_append(q->mem_ctx, q->part1, - "%s = '%s',", name, esc_value); - } else { - q->part1 = - talloc_asprintf_append(q->mem_ctx, q->part1, "%s,", name); - q->part2 = - talloc_asprintf_append(q->mem_ctx, q->part2, "'%s',", - esc_value); - } - - SAFE_FREE(esc_value); - - return NT_STATUS_OK; -} - -#define config_value(data,name,default_value) \ - lp_parm_const_string(GLOBAL_SECTION_SNUM, (data)->location, name, default_value) - -static const char * config_value_write(pdb_mysql_data * data, const char *name, const char *default_value) { - char const *v = NULL; - char const *swrite = NULL; - - v = lp_parm_const_string(GLOBAL_SECTION_SNUM, data->location, name, default_value); - - if (!v) - return NULL; - - swrite = strrchr(v, ':'); - - /* Default to the same field as read field */ - if (!swrite) - return v; - - swrite++; - - /* If the field is 0 chars long, we shouldn't write to it */ - if (!strlen(swrite) || !strcmp(swrite, "NULL")) - return NULL; - - /* Otherwise, use the additionally specified */ - return swrite; -} - -static const char * config_value_read(pdb_mysql_data * data, const char *name, const char *default_value) -{ - char *v = NULL; - char *swrite; - - v = lp_parm_talloc_string(GLOBAL_SECTION_SNUM, data->location, name, default_value); - - if (!v) - return "NULL"; - - swrite = strrchr(v, ':'); - - /* If no write is specified, there are no problems */ - if (!swrite) { - if (strlen(v) == 0) - return "NULL"; - return (const char *)v; - } - - /* Otherwise, we have to cut the ':write_part' */ - *swrite = '\0'; - if (strlen(v) == 0) - return "NULL"; - - return (const char *)v; -} +#define config_value( data, name, default_value ) \ + lp_parm_const_string( GLOBAL_SECTION_SNUM, (data)->location, name, default_value ) -/* Wrapper for atol that returns 0 if 'a' points to NULL */ -static long xatol(const char *a) +static long xatol(const char *d) { - long ret = 0; - - if (a != NULL) - ret = atol(a); - - return ret; + if(!d) return 0; + return atol(d); } static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u) @@ -285,72 +133,8 @@ static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update) return NT_STATUS_INVALID_HANDLE; } - asprintf(&query, - "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s", - config_value_read(data, "logon time column", - CONFIG_LOGON_TIME_DEFAULT), - config_value_read(data, "logoff time column", - CONFIG_LOGOFF_TIME_DEFAULT), - config_value_read(data, "kickoff time column", - CONFIG_KICKOFF_TIME_DEFAULT), - config_value_read(data, "pass last set time column", - CONFIG_PASS_LAST_SET_TIME_DEFAULT), - config_value_read(data, "pass can change time column", - CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT), - config_value_read(data, "pass must change time column", - CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT), - config_value_read(data, "username column", - CONFIG_USERNAME_DEFAULT), - config_value_read(data, "domain column", - CONFIG_DOMAIN_DEFAULT), - config_value_read(data, "nt username column", - CONFIG_NT_USERNAME_DEFAULT), - config_value_read(data, "fullname column", - CONFIG_FULLNAME_DEFAULT), - config_value_read(data, "home dir column", - CONFIG_HOME_DIR_DEFAULT), - config_value_read(data, "dir drive column", - CONFIG_DIR_DRIVE_DEFAULT), - config_value_read(data, "logon script column", - CONFIG_LOGON_SCRIPT_DEFAULT), - config_value_read(data, "profile path column", - CONFIG_PROFILE_PATH_DEFAULT), - config_value_read(data, "acct desc column", - CONFIG_ACCT_DESC_DEFAULT), - config_value_read(data, "workstations column", - CONFIG_WORKSTATIONS_DEFAULT), - config_value_read(data, "unknown string column", - CONFIG_UNKNOWN_STR_DEFAULT), - config_value_read(data, "munged dial column", - CONFIG_MUNGED_DIAL_DEFAULT), - config_value_read(data, "user sid column", - CONFIG_USER_SID_DEFAULT), - config_value_read(data, "group sid column", - CONFIG_GROUP_SID_DEFAULT), - config_value_read(data, "lanman pass column", - CONFIG_LM_PW_DEFAULT), - config_value_read(data, "nt pass column", - CONFIG_NT_PW_DEFAULT), - config_value_read(data, "plain pass column", - CONFIG_PLAIN_PW_DEFAULT), - config_value_read(data, "acct ctrl column", - CONFIG_ACCT_CTRL_DEFAULT), - config_value_read(data, "unknown 3 column", - CONFIG_UNKNOWN_3_DEFAULT), - config_value_read(data, "logon divs column", - CONFIG_LOGON_DIVS_DEFAULT), - config_value_read(data, "hours len column", - CONFIG_HOURS_LEN_DEFAULT), - config_value_read(data, "bad password count column", - CONFIG_BAD_PASSWORD_COUNT_DEFAULT), - config_value_read(data, "logon count column", - CONFIG_LOGON_COUNT_DEFAULT), - config_value_read(data, "unknown 6 column", - CONFIG_UNKNOWN_6_DEFAULT), - config_value(data, "table", CONFIG_TABLE_DEFAULT) - ); - DEBUG(5, ("Executing query %s\n", query)); - + query = sql_account_query_select(data->location, update, SQL_SEARCH_NONE, NULL); + ret = mysql_query(data->handle, query); SAFE_FREE(query); @@ -416,7 +200,7 @@ static NTSTATUS mysqlsam_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT * } static NTSTATUS mysqlsam_select_by_field(struct pdb_methods * methods, SAM_ACCOUNT * user, - const char *field, const char *sname) + enum sql_search_field field, const char *sname) { char *esc_sname; char *query; @@ -433,10 +217,6 @@ static NTSTATUS mysqlsam_select_by_field(struct pdb_methods * methods, SAM_ACCOU return NT_STATUS_NO_MEMORY; } - DEBUG(5, - ("mysqlsam_select_by_field: getting data where %s = %s(nonescaped)\n", - field, sname)); - tmp_sname = smb_xstrdup(sname); /* Escape sname */ @@ -451,71 +231,8 @@ static NTSTATUS mysqlsam_select_by_field(struct pdb_methods * methods, SAM_ACCOU return NT_STATUS_INVALID_PARAMETER; } - asprintf(&query, - "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s WHERE %s = '%s'", - config_value_read(data, "logon time column", - CONFIG_LOGON_TIME_DEFAULT), - config_value_read(data, "logoff time column", - CONFIG_LOGOFF_TIME_DEFAULT), - config_value_read(data, "kickoff time column", - CONFIG_KICKOFF_TIME_DEFAULT), - config_value_read(data, "pass last set time column", - CONFIG_PASS_LAST_SET_TIME_DEFAULT), - config_value_read(data, "pass can change time column", - CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT), - config_value_read(data, "pass must change time column", - CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT), - config_value_read(data, "username column", - CONFIG_USERNAME_DEFAULT), - config_value_read(data, "domain column", - CONFIG_DOMAIN_DEFAULT), - config_value_read(data, "nt username column", - CONFIG_NT_USERNAME_DEFAULT), - config_value_read(data, "fullname column", - CONFIG_FULLNAME_DEFAULT), - config_value_read(data, "home dir column", - CONFIG_HOME_DIR_DEFAULT), - config_value_read(data, "dir drive column", - CONFIG_DIR_DRIVE_DEFAULT), - config_value_read(data, "logon script column", - CONFIG_LOGON_SCRIPT_DEFAULT), - config_value_read(data, "profile path column", - CONFIG_PROFILE_PATH_DEFAULT), - config_value_read(data, "acct desc column", - CONFIG_ACCT_DESC_DEFAULT), - config_value_read(data, "workstations column", - CONFIG_WORKSTATIONS_DEFAULT), - config_value_read(data, "unknown string column", - CONFIG_UNKNOWN_STR_DEFAULT), - config_value_read(data, "munged dial column", - CONFIG_MUNGED_DIAL_DEFAULT), - config_value_read(data, "user sid column", - CONFIG_USER_SID_DEFAULT), - config_value_read(data, "group sid column", - CONFIG_GROUP_SID_DEFAULT), - config_value_read(data, "lanman pass column", - CONFIG_LM_PW_DEFAULT), - config_value_read(data, "nt pass column", - CONFIG_NT_PW_DEFAULT), - config_value_read(data, "plain pass column", - CONFIG_PLAIN_PW_DEFAULT), - config_value_read(data, "acct ctrl column", - CONFIG_ACCT_CTRL_DEFAULT), - config_value_read(data, "unknown 3 column", - CONFIG_UNKNOWN_3_DEFAULT), - config_value_read(data, "logon divs column", - CONFIG_LOGON_DIVS_DEFAULT), - config_value_read(data, "hours len column", - CONFIG_HOURS_LEN_DEFAULT), - config_value_read(data, "bad password count column", - CONFIG_BAD_PASSWORD_COUNT_DEFAULT), - config_value_read(data, "logon count column", - CONFIG_LOGON_COUNT_DEFAULT), - config_value_read(data, "unknown 6 column", - CONFIG_UNKNOWN_6_DEFAULT), - config_value(data, "table", CONFIG_TABLE_DEFAULT), field, - esc_sname); - + query = sql_account_query_select(data->location, True, field, esc_sname); + SAFE_FREE(esc_sname); DEBUG(5, ("Executing query %s\n", query)); @@ -561,8 +278,7 @@ static NTSTATUS mysqlsam_getsampwnam(struct pdb_methods *methods, SAM_ACCOUNT * } return mysqlsam_select_by_field(methods, user, - config_value_read(data, "username column", - CONFIG_USERNAME_DEFAULT), sname); + SQL_SEARCH_USER_NAME, sname); } @@ -580,9 +296,7 @@ static NTSTATUS mysqlsam_getsampwsid(struct pdb_methods *methods, SAM_ACCOUNT * sid_to_string(sid_str, sid); - return mysqlsam_select_by_field(methods, user, - config_value_read(data, "user sid column", - CONFIG_USER_SID_DEFAULT), sid_str); + return mysqlsam_select_by_field(methods, user, SQL_SEARCH_USER_SID, sid_str); } /*************************************************************************** @@ -631,10 +345,7 @@ static NTSTATUS mysqlsam_delete_sam_account(struct pdb_methods *methods, SAFE_FREE(tmp_sname); - asprintf(&query, "DELETE FROM %s WHERE %s = '%s'", - config_value(data, "table", CONFIG_TABLE_DEFAULT), - config_value_read(data, "username column", - CONFIG_USERNAME_DEFAULT), esc); + query = sql_account_query_delete(data->location, esc); SAFE_FREE(esc); @@ -656,11 +367,8 @@ static NTSTATUS mysqlsam_delete_sam_account(struct pdb_methods *methods, static NTSTATUS mysqlsam_replace_sam_account(struct pdb_methods *methods, const SAM_ACCOUNT * newpwd, char isupdate) { - pstring temp; - char *field; struct pdb_mysql_data *data; - pdb_mysql_query query; - fstring sid_str; + char *query; if (!methods) { DEBUG(0, ("invalid methods!\n")); @@ -673,200 +381,18 @@ static NTSTATUS mysqlsam_replace_sam_account(struct pdb_methods *methods, DEBUG(0, ("invalid handle!\n")); return NT_STATUS_INVALID_HANDLE; } - query.update = isupdate; - - /* I know this is somewhat overkill but only the talloc - * functions have asprint_append and the 'normal' asprintf - * is a GNU extension */ - query.mem_ctx = talloc_init("mysqlsam_replace_sam_account"); - query.part2 = talloc_asprintf(query.mem_ctx, "%s", ""); - if (query.update) { - query.part1 = - talloc_asprintf(query.mem_ctx, "UPDATE %s SET ", - config_value(data, "table", - CONFIG_TABLE_DEFAULT)); - } else { - query.part1 = - talloc_asprintf(query.mem_ctx, "INSERT INTO %s (", - config_value(data, "table", - CONFIG_TABLE_DEFAULT)); - } - - pdb_mysql_int_field(methods, &query, - config_value_write(data, "acct ctrl column", - CONFIG_ACCT_CTRL_DEFAULT), - pdb_get_acct_ctrl(newpwd)); - - if (pdb_get_init_flags(newpwd, PDB_LOGONTIME) != PDB_DEFAULT) { - pdb_mysql_int_field(methods, &query, - config_value_write(data, - "logon time column", - CONFIG_LOGON_TIME_DEFAULT), - pdb_get_logon_time(newpwd)); - } - - if (pdb_get_init_flags(newpwd, PDB_LOGOFFTIME) != PDB_DEFAULT) { - pdb_mysql_int_field(methods, &query, - config_value_write(data, - "logoff time column", - CONFIG_LOGOFF_TIME_DEFAULT), - pdb_get_logoff_time(newpwd)); - } - if (pdb_get_init_flags(newpwd, PDB_KICKOFFTIME) != PDB_DEFAULT) { - pdb_mysql_int_field(methods, &query, - config_value_write(data, - "kickoff time column", - CONFIG_KICKOFF_TIME_DEFAULT), - pdb_get_kickoff_time(newpwd)); - } - - if (pdb_get_init_flags(newpwd, PDB_CANCHANGETIME) != PDB_DEFAULT) { - pdb_mysql_int_field(methods, &query, - config_value_write(data, - "pass can change time column", - CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT), - pdb_get_pass_can_change_time(newpwd)); - } - - if (pdb_get_init_flags(newpwd, PDB_MUSTCHANGETIME) != PDB_DEFAULT) { - pdb_mysql_int_field(methods, &query, - config_value_write(data, - "pass must change time column", - CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT), - pdb_get_pass_must_change_time(newpwd)); - } - - if (pdb_get_pass_last_set_time(newpwd)) { - pdb_mysql_int_field(methods, &query, - config_value_write(data, - "pass last set time column", - CONFIG_PASS_LAST_SET_TIME_DEFAULT), - pdb_get_pass_last_set_time(newpwd)); - } - - if (pdb_get_hours_len(newpwd)) { - pdb_mysql_int_field(methods, &query, - config_value_write(data, - "hours len column", - CONFIG_HOURS_LEN_DEFAULT), - pdb_get_hours_len(newpwd)); - } - - if (pdb_get_logon_divs(newpwd)) { - pdb_mysql_int_field(methods, &query, - config_value_write(data, - "logon divs column", - CONFIG_LOGON_DIVS_DEFAULT), - pdb_get_logon_divs(newpwd)); - } - - pdb_mysql_string_field(methods, &query, - config_value_write(data, "user sid column", - CONFIG_USER_SID_DEFAULT), - sid_to_string(sid_str, - pdb_get_user_sid(newpwd))); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, "group sid column", - CONFIG_GROUP_SID_DEFAULT), - sid_to_string(sid_str, - pdb_get_group_sid(newpwd))); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, "username column", - CONFIG_USERNAME_DEFAULT), - pdb_get_username(newpwd)); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, "domain column", - CONFIG_DOMAIN_DEFAULT), - pdb_get_domain(newpwd)); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, - "nt username column", - CONFIG_NT_USERNAME_DEFAULT), - pdb_get_nt_username(newpwd)); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, "fullname column", - CONFIG_FULLNAME_DEFAULT), - pdb_get_fullname(newpwd)); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, - "logon script column", - CONFIG_LOGON_SCRIPT_DEFAULT), - pdb_get_logon_script(newpwd)); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, - "profile path column", - CONFIG_PROFILE_PATH_DEFAULT), - pdb_get_profile_path(newpwd)); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, "dir drive column", - CONFIG_DIR_DRIVE_DEFAULT), - pdb_get_dir_drive(newpwd)); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, "home dir column", - CONFIG_HOME_DIR_DEFAULT), - pdb_get_homedir(newpwd)); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, - "workstations column", - CONFIG_WORKSTATIONS_DEFAULT), - pdb_get_workstations(newpwd)); - - pdb_mysql_string_field(methods, &query, - config_value_write(data, - "unknown string column", - CONFIG_UNKNOWN_STR_DEFAULT), - pdb_get_workstations(newpwd)); - - pdb_sethexpwd(temp, pdb_get_lanman_passwd(newpwd), - pdb_get_acct_ctrl(newpwd)); - pdb_mysql_string_field(methods, &query, - config_value_write(data, - "lanman pass column", - CONFIG_LM_PW_DEFAULT), temp); - - pdb_sethexpwd(temp, pdb_get_nt_passwd(newpwd), - pdb_get_acct_ctrl(newpwd)); - pdb_mysql_string_field(methods, &query, - config_value_write(data, "nt pass column", - CONFIG_NT_PW_DEFAULT), temp); - - if (query.update) { - query.part1[strlen(query.part1) - 1] = '\0'; - query.part1 = - talloc_asprintf_append(query.mem_ctx, query.part1, - " WHERE %s = '%s'", - config_value_read(data, - "user sid column", - CONFIG_USER_SID_DEFAULT), - sid_to_string(sid_str, pdb_get_user_sid (newpwd))); - } else { - query.part2[strlen(query.part2) - 1] = ')'; - query.part1[strlen(query.part1) - 1] = ')'; - query.part1 = - talloc_asprintf_append(query.mem_ctx, query.part1, - " VALUES (%s", query.part2); - } - - DEBUG(0, ("%s\n", query.part1)); + query = sql_account_query_update(data->location, newpwd, isupdate); + /* Execute the query */ - if (mysql_query(data->handle, query.part1)) { + if (mysql_query(data->handle, query)) { DEBUG(0, - ("Error executing %s, %s\n", query.part1, + ("Error executing %s, %s\n", query, mysql_error(data->handle))); return NT_STATUS_INVALID_PARAMETER; } - talloc_destroy(query.mem_ctx); + SAFE_FREE(query); + return NT_STATUS_OK; } @@ -886,7 +412,6 @@ static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_metho { NTSTATUS nt_status; struct pdb_mysql_data *data; - const char *sid_column, *username_column; mysqlsam_debug_level = debug_add_class("mysqlsam"); if (mysqlsam_debug_level == -1) { @@ -944,11 +469,8 @@ static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_metho return NT_STATUS_UNSUCCESSFUL; } - sid_column = config_value_read(data, "user sid column", CONFIG_USER_SID_DEFAULT); - username_column = config_value_read(data, "username column", CONFIG_USERNAME_DEFAULT); - if(!strcmp(sid_column,"NULL") || !strcmp(username_column, "NULL")) { - DEBUG(0,("Please specify both a valid 'user sid column' and a valid 'username column' in smb.conf\n")); - return NT_STATUS_UNSUCCESSFUL; + if(!sql_account_config_valid(data->location)) { + return NT_STATUS_INVALID_PARAMETER; } /* Process correct entry in $HOME/.my.conf */ diff --git a/source3/passdb/pdb_pgsql.c b/source3/passdb/pdb_pgsql.c new file mode 100644 index 0000000000..61c620e092 --- /dev/null +++ b/source3/passdb/pdb_pgsql.c @@ -0,0 +1,489 @@ +/* + * PostgresSQL password backend for samba + * Copyright (C) Hamish Friedlander 2003 + * Copyright (C) Jelmer Vernooij 2004 + * + * 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 the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 675 + * Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include + +#define CONFIG_HOST_DEFAULT "localhost" +#define CONFIG_USER_DEFAULT "samba" +#define CONFIG_PASS_DEFAULT "" +#define CONFIG_PORT_DEFAULT "5432" +#define CONFIG_DB_DEFAULT "samba" + +/* handles for doing db transactions */ +typedef struct pdb_pgsql_data { + PGconn *handle ; + PGresult *pwent ; + long currow ; + + const char *location ; +} pdb_pgsql_data ; + +#define SET_DATA(data,methods) { \ + if(!methods){ \ + DEBUG(0, ("invalid methods!\n")); \ + return NT_STATUS_INVALID_PARAMETER; \ + } \ + data = (struct pdb_pgsql_data *)methods->private_data; \ + if(!data || !(data->handle)){ \ + DEBUG(0, ("invalid handle!\n")); \ + return NT_STATUS_INVALID_HANDLE; \ + } \ +} + +#define SET_DATA_QUIET(data,methods) { \ + if(!methods){ \ + DEBUG(0, ("invalid methods!\n")); \ + return ; \ + } \ + data = (struct pdb_pgsql_data *)methods->private_data; \ + if(!data || !(data->handle)){ \ + DEBUG(0, ("invalid handle!\n")); \ + return ; \ + } \ +} + + +#define config_value( data, name, default_value ) \ + lp_parm_const_string( GLOBAL_SECTION_SNUM, (data)->location, name, default_value ) + +static long PQgetlong( PGresult *r, long row, long col ) +{ + if ( PQgetisnull( r, row, col ) ) return 0 ; + + return atol( PQgetvalue( r, row, col ) ) ; +} + +static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u ) +{ + pstring temp ; + DOM_SID sid ; + + if ( row >= PQntuples( r ) ) return NT_STATUS_INVALID_PARAMETER ; + + pdb_set_logon_time ( u, PQgetlong ( r, row, 0 ), PDB_SET ) ; + pdb_set_logoff_time ( u, PQgetlong ( r, row, 1 ), PDB_SET ) ; + pdb_set_kickoff_time ( u, PQgetlong ( r, row, 2 ), PDB_SET ) ; + pdb_set_pass_last_set_time ( u, PQgetlong ( r, row, 3 ), PDB_SET ) ; + pdb_set_pass_can_change_time ( u, PQgetlong ( r, row, 4 ), PDB_SET ) ; + pdb_set_pass_must_change_time( u, PQgetlong ( r, row, 5 ), PDB_SET ) ; + pdb_set_username ( u, PQgetvalue( r, row, 6 ), PDB_SET ) ; + pdb_set_domain ( u, PQgetvalue( r, row, 7 ), PDB_SET ) ; + pdb_set_nt_username ( u, PQgetvalue( r, row, 8 ), PDB_SET ) ; + pdb_set_fullname ( u, PQgetvalue( r, row, 9 ), PDB_SET ) ; + pdb_set_homedir ( u, PQgetvalue( r, row, 10 ), PDB_SET ) ; + pdb_set_dir_drive ( u, PQgetvalue( r, row, 11 ), PDB_SET ) ; + pdb_set_logon_script ( u, PQgetvalue( r, row, 12 ), PDB_SET ) ; + pdb_set_profile_path ( u, PQgetvalue( r, row, 13 ), PDB_SET ) ; + pdb_set_acct_desc ( u, PQgetvalue( r, row, 14 ), PDB_SET ) ; + pdb_set_workstations ( u, PQgetvalue( r, row, 15 ), PDB_SET ) ; + pdb_set_unknown_str ( u, PQgetvalue( r, row, 16 ), PDB_SET ) ; + pdb_set_munged_dial ( u, PQgetvalue( r, row, 17 ), PDB_SET ) ; + + pdb_set_acct_ctrl ( u, PQgetlong ( r, row, 23 ), PDB_SET ) ; + pdb_set_unknown_3 ( u, PQgetlong ( r, row, 24 ), PDB_SET ) ; + pdb_set_logon_divs ( u, PQgetlong ( r, row, 25 ), PDB_SET ) ; + pdb_set_hours_len ( u, PQgetlong ( r, row, 26 ), PDB_SET ) ; + pdb_set_logon_count ( u, PQgetlong ( r, row, 27 ), PDB_SET ) ; + pdb_set_unknown_6 ( u, PQgetlong ( r, row, 28 ), PDB_SET ) ; + + if ( !PQgetisnull( r, row, 18 ) ) string_to_sid( &sid, PQgetvalue( r, row, 18 ) ) ; + pdb_set_user_sid ( u, &sid, PDB_SET ) ; + if ( !PQgetisnull( r, row, 19 ) ) string_to_sid( &sid, PQgetvalue( r, row, 19 ) ) ; + pdb_set_group_sid( u, &sid, PDB_SET ) ; + + if ( pdb_gethexpwd( PQgetvalue( r, row, 20 ), temp ), PDB_SET ) pdb_set_lanman_passwd( u, temp, PDB_SET ) ; + if ( pdb_gethexpwd( PQgetvalue( r, row, 21 ), temp ), PDB_SET ) pdb_set_nt_passwd ( u, temp, PDB_SET ) ; + + /* Only use plaintext password storage when lanman and nt are NOT used */ + if ( PQgetisnull( r, row, 20 ) || PQgetisnull( r, row, 21 ) ) pdb_set_plaintext_passwd( u, PQgetvalue( r, row, 22 ) ) ; + + return NT_STATUS_OK ; +} + +static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update) +{ + struct pdb_pgsql_data *data ; + char *query ; + NTSTATUS retval ; + + SET_DATA( data, methods ) ; + + query = sql_account_query_select(data->location, update, SQL_SEARCH_NONE, NULL); + + /* Do it */ + DEBUG( 5, ("Executing query %s\n", query) ) ; + data->pwent = PQexec( data->handle, query ) ; + data->currow = 0 ; + + /* Result? */ + if ( data->pwent == NULL ) + { + DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( data->handle ) ) ) ; + retval = NT_STATUS_UNSUCCESSFUL ; + } + else if ( PQresultStatus( data->pwent ) != PGRES_TUPLES_OK ) + { + DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( data->pwent ) ) ) ; + retval = NT_STATUS_UNSUCCESSFUL ; + } + else + { + DEBUG( 5, ("pgsqlsam_setsampwent succeeded(%llu results)!\n", PQntuples(data->pwent)) ) ; + retval = NT_STATUS_OK ; + } + + SAFE_FREE(query); + return retval ; +} + +/*************************************************************** + End enumeration of the passwd list. + ****************************************************************/ + +static void pgsqlsam_endsampwent(struct pdb_methods *methods) +{ + struct pdb_pgsql_data *data ; + + SET_DATA_QUIET( data, methods ) ; + + if (data->pwent != NULL) + { + PQclear( data->pwent ) ; + } + + data->pwent = NULL ; + data->currow = 0 ; + + DEBUG( 5, ("pgsql_endsampwent called\n") ) ; +} + +/***************************************************************** + Get one SAM_ACCOUNT from the list (next in line) + *****************************************************************/ + +static NTSTATUS pgsqlsam_getsampwent( struct pdb_methods *methods, SAM_ACCOUNT *user ) +{ + struct pdb_pgsql_data *data; + NTSTATUS retval ; + + SET_DATA( data, methods ) ; + + if ( data->pwent == NULL ) + { + DEBUG( 0, ("invalid pwent\n") ) ; + return NT_STATUS_INVALID_PARAMETER ; + } + + retval = row_to_sam_account( data->pwent, data->currow, user ) ; + data->currow++ ; + + return retval ; +} + +static NTSTATUS pgsqlsam_select_by_field ( struct pdb_methods *methods, SAM_ACCOUNT *user, enum sql_search_field field, const char *sname ) +{ + struct pdb_pgsql_data *data ; + + char *esc ; + char *query ; + + PGresult *result ; + NTSTATUS retval ; + + SET_DATA(data, methods); + + if ( user == NULL ) + { + DEBUG( 0, ("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n") ) ; + return NT_STATUS_INVALID_PARAMETER; + } + + DEBUG( 5, ("pgsqlsam_select_by_field: getting data where %d = %s(nonescaped)\n", field, sname) ) ; + + /* Escape sname */ + esc = malloc(strlen(sname) * 2 + 1); + if ( !esc ) + { + DEBUG(0, ("Can't allocate memory to store escaped name\n")); + return NT_STATUS_NO_MEMORY; + } + + //tmp_sname = smb_xstrdup(sname); + PQescapeString( esc, sname, strlen(sname) ) ; + + query = sql_account_query_select(data->location, True, field, esc); + + /* Do it */ + DEBUG( 5, ("Executing query %s\n", query) ) ; + result = PQexec( data->handle, query ) ; + + /* Result? */ + if ( result == NULL ) + { + DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( data->handle ) ) ) ; + retval = NT_STATUS_UNSUCCESSFUL ; + } + else if ( PQresultStatus( result ) != PGRES_TUPLES_OK ) + { + DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( result ) ) ) ; + retval = NT_STATUS_UNSUCCESSFUL ; + } + else + { + retval = row_to_sam_account( result, 0, user ) ; + } + + SAFE_FREE( esc ) ; + SAFE_FREE( query ) ; + + PQclear( result ) ; + + return retval ; +} + +/****************************************************************** + Lookup a name in the SAM database + ******************************************************************/ + +static NTSTATUS pgsqlsam_getsampwnam ( struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname ) +{ + struct pdb_pgsql_data *data; + + SET_DATA(data, methods); + + if ( !sname ) + { + DEBUG( 0, ("invalid name specified") ) ; + return NT_STATUS_INVALID_PARAMETER; + } + + return pgsqlsam_select_by_field( methods, user, SQL_SEARCH_USER_NAME, sname ) ; +} + + +/*************************************************************************** + Search by sid + **************************************************************************/ + +static NTSTATUS pgsqlsam_getsampwsid ( struct pdb_methods *methods, SAM_ACCOUNT *user, const DOM_SID *sid ) +{ + struct pdb_pgsql_data *data; + fstring sid_str; + + SET_DATA( data, methods ) ; + + sid_to_string( sid_str, sid ) ; + + return pgsqlsam_select_by_field( methods, user, SQL_SEARCH_USER_SID, sid_str ) ; +} + +/*************************************************************************** + Delete a SAM_ACCOUNT + ****************************************************************************/ + +static NTSTATUS pgsqlsam_delete_sam_account( struct pdb_methods *methods, SAM_ACCOUNT *sam_pass ) +{ + struct pdb_pgsql_data *data ; + + const char *sname = pdb_get_username( sam_pass ) ; + char *esc ; + char *query ; + + PGresult *result ; + NTSTATUS retval ; + + SET_DATA(data, methods); + + if ( !sname ) + { + DEBUG( 0, ("invalid name specified\n") ) ; + return NT_STATUS_INVALID_PARAMETER ; + } + + /* Escape sname */ + esc = malloc(strlen(sname) * 2 + 1); + if ( !esc ) + { + DEBUG(0, ("Can't allocate memory to store escaped name\n")); + return NT_STATUS_NO_MEMORY; + } + + PQescapeString( esc, sname, strlen(sname) ) ; + + query = sql_account_query_delete(data->location, esc); + + /* Do it */ + result = PQexec( data->handle, query ) ; + + if ( result == NULL ) + { + DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( data->handle ) ) ) ; + retval = NT_STATUS_UNSUCCESSFUL ; + } + else if ( PQresultStatus( result ) != PGRES_COMMAND_OK ) + { + DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( result ) ) ) ; + retval = NT_STATUS_UNSUCCESSFUL ; + } + else + { + DEBUG( 5, ("User '%s' deleted\n", sname) ) ; + retval = NT_STATUS_OK ; + } + + SAFE_FREE( esc ) ; + SAFE_FREE( query ) ; + + return retval ; +} + +static NTSTATUS pgsqlsam_replace_sam_account( struct pdb_methods *methods, const SAM_ACCOUNT *newpwd, char isupdate ) +{ + struct pdb_pgsql_data *data ; + char *query; + PGresult *result ; + + if ( !methods ) + { + DEBUG( 0, ("invalid methods!\n") ) ; + return NT_STATUS_INVALID_PARAMETER ; + } + + data = (struct pdb_pgsql_data *) methods->private_data ; + + if ( data == NULL || data->handle == NULL ) + { + DEBUG( 0, ("invalid handle!\n") ) ; + return NT_STATUS_INVALID_HANDLE ; + } + + query = sql_account_query_update(data->location, newpwd, isupdate); + + result = PQexec( data->handle, query ) ; + + + /* Execute the query */ + if ( result == NULL ) + { + DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( data->handle ) ) ) ; + return NT_STATUS_INVALID_PARAMETER; + } + else if ( PQresultStatus( result ) != PGRES_COMMAND_OK ) + { + DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( result ) ) ) ; + return NT_STATUS_INVALID_PARAMETER; + } + SAFE_FREE(query); + + return NT_STATUS_OK; +} + +static NTSTATUS pgsqlsam_add_sam_account ( struct pdb_methods *methods, SAM_ACCOUNT *newpwd ) +{ + return pgsqlsam_replace_sam_account( methods, newpwd, 0 ) ; +} + +static NTSTATUS pgsqlsam_update_sam_account ( struct pdb_methods *methods, SAM_ACCOUNT *newpwd ) +{ + return pgsqlsam_replace_sam_account( methods, newpwd, 1 ) ; +} + +static NTSTATUS pgsqlsam_init ( struct pdb_context *pdb_context, struct pdb_methods **pdb_method, const char *location ) +{ + NTSTATUS nt_status ; + struct pdb_pgsql_data *data ; + + if ( !pdb_context ) + { + DEBUG( 0, ("invalid pdb_methods specified\n") ) ; + return NT_STATUS_UNSUCCESSFUL; + } + + if (!NT_STATUS_IS_OK + (nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) { + return nt_status; + } + + (*pdb_method)->name = "pgsqlsam" ; + + (*pdb_method)->setsampwent = pgsqlsam_setsampwent ; + (*pdb_method)->endsampwent = pgsqlsam_endsampwent ; + (*pdb_method)->getsampwent = pgsqlsam_getsampwent ; + (*pdb_method)->getsampwnam = pgsqlsam_getsampwnam ; + (*pdb_method)->getsampwsid = pgsqlsam_getsampwsid ; + (*pdb_method)->add_sam_account = pgsqlsam_add_sam_account ; + (*pdb_method)->update_sam_account = pgsqlsam_update_sam_account ; + (*pdb_method)->delete_sam_account = pgsqlsam_delete_sam_account ; + + data = talloc( pdb_context->mem_ctx, sizeof( struct pdb_pgsql_data ) ) ; + (*pdb_method)->private_data = data ; + data->handle = NULL ; + data->pwent = NULL ; + + if ( !location ) + { + DEBUG( 0, ("No identifier specified. Check the Samba HOWTO Collection for details\n") ) ; + return NT_STATUS_INVALID_PARAMETER; + } + + data->location = smb_xstrdup( location ) ; + + if(!sql_account_config_valid(data->location)) { + return NT_STATUS_INVALID_PARAMETER; + } + + DEBUG + ( + 1, + ( + "Connecting to database server, host: %s, user: %s, password: XXXXXX, database: %s, port: %s\n", + config_value( data, "pgsql host" , CONFIG_HOST_DEFAULT ), + config_value( data, "pgsql user" , CONFIG_USER_DEFAULT ), + config_value( data, "pgsql database", CONFIG_DB_DEFAULT ), + config_value( data, "pgsql port" , CONFIG_PORT_DEFAULT ) + ) + ) ; + + /* Do the pgsql initialization */ + data->handle = PQsetdbLogin( + config_value( data, "pgsql host" , CONFIG_HOST_DEFAULT ), + config_value( data, "pgsql port" , CONFIG_PORT_DEFAULT ), + NULL, + NULL, + config_value( data, "pgsql database", CONFIG_DB_DEFAULT ), + config_value( data, "pgsql user" , CONFIG_USER_DEFAULT ), + config_value( data, "pgsql password", CONFIG_PASS_DEFAULT ) + ) ; + + if ( PQstatus( data->handle ) != CONNECTION_OK ) + { + DEBUG( 0, ("Failed to connect to pgsql database: error: %s\n", PQerrorMessage( data->handle )) ) ; + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG( 5, ("Connected to pgsql database\n") ) ; + return NT_STATUS_OK; +} + +NTSTATUS pdb_pgsql_init(void) +{ + return smb_register_passdb( PASSDB_INTERFACE_VERSION, "pgsql", pgsqlsam_init ) ; +} diff --git a/source3/passdb/pdb_sql.c b/source3/passdb/pdb_sql.c new file mode 100644 index 0000000000..b87004e019 --- /dev/null +++ b/source3/passdb/pdb_sql.c @@ -0,0 +1,496 @@ +/* + * Common PDB SQL backend functions + * Copyright (C) Jelmer Vernooij 2003-2004 + * + * 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 the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 675 + * Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +#define CONFIG_TABLE_DEFAULT "user" +#define CONFIG_LOGON_TIME_DEFAULT "logon_time" +#define CONFIG_LOGOFF_TIME_DEFAULT "logoff_time" +#define CONFIG_KICKOFF_TIME_DEFAULT "kickoff_time" +#define CONFIG_PASS_LAST_SET_TIME_DEFAULT "pass_last_set_time" +#define CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT "pass_can_change_time" +#define CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT "pass_must_change_time" +#define CONFIG_USERNAME_DEFAULT "username" +#define CONFIG_DOMAIN_DEFAULT "domain" +#define CONFIG_NT_USERNAME_DEFAULT "nt_username" +#define CONFIG_FULLNAME_DEFAULT "nt_fullname" +#define CONFIG_HOME_DIR_DEFAULT "home_dir" +#define CONFIG_DIR_DRIVE_DEFAULT "dir_drive" +#define CONFIG_LOGON_SCRIPT_DEFAULT "logon_script" +#define CONFIG_PROFILE_PATH_DEFAULT "profile_path" +#define CONFIG_ACCT_DESC_DEFAULT "acct_desc" +#define CONFIG_WORKSTATIONS_DEFAULT "workstations" +#define CONFIG_UNKNOWN_STR_DEFAULT "unknown_str" +#define CONFIG_MUNGED_DIAL_DEFAULT "munged_dial" +#define CONFIG_USER_SID_DEFAULT "user_sid" +#define CONFIG_GROUP_SID_DEFAULT "group_sid" +#define CONFIG_LM_PW_DEFAULT "lm_pw" +#define CONFIG_NT_PW_DEFAULT "nt_pw" +#define CONFIG_PLAIN_PW_DEFAULT "NULL" +#define CONFIG_ACCT_CTRL_DEFAULT "acct_ctrl" +#define CONFIG_UNKNOWN_3_DEFAULT "unknown_3" +#define CONFIG_LOGON_DIVS_DEFAULT "logon_divs" +#define CONFIG_HOURS_LEN_DEFAULT "hours_len" +#define CONFIG_BAD_PASSWORD_COUNT_DEFAULT "bad_password_count" +#define CONFIG_LOGON_COUNT_DEFAULT "logon_count" +#define CONFIG_UNKNOWN_6_DEFAULT "unknown_6" + +/* Used to construct insert and update queries */ + +typedef struct pdb_sql_query { + char update; + TALLOC_CTX *mem_ctx; + char *part1; + char *part2; +} pdb_sql_query; + +static void pdb_sql_int_field(struct pdb_sql_query *q, const char *name, int value) +{ + if (!name || strchr(name, '\'')) + return; /* This field shouldn't be set by us */ + + if (q->update) { + q->part1 = + talloc_asprintf_append(q->mem_ctx, q->part1, + "%s = %d,", name, value); + } else { + q->part1 = + talloc_asprintf_append(q->mem_ctx, q->part1, "%s,", name); + q->part2 = + talloc_asprintf_append(q->mem_ctx, q->part2, "%d,", value); + } +} + +char *sql_escape_string(const char *unesc) +{ + char *esc = malloc(strlen(unesc) * 2 + 3); + size_t pos_unesc = 0, pos_esc = 0; + + for(pos_unesc = 0; unesc[pos_unesc]; pos_unesc++) { + switch(unesc[pos_unesc]) { + case '\\': + case '\'': + case '"': + esc[pos_esc] = '\\'; pos_esc++; + default: + esc[pos_esc] = unesc[pos_unesc]; pos_esc++; + break; + } + } + + esc[pos_esc] = '\0'; + + return esc; +} + +static NTSTATUS pdb_sql_string_field(struct pdb_sql_query *q, + const char *name, const char *value) +{ + char *esc_value; + + if (!name || !value || !strcmp(value, "") || strchr(name, '\'')) + return NT_STATUS_INVALID_PARAMETER; /* This field shouldn't be set by module */ + + esc_value = sql_escape_string(value); + + if (q->update) { + q->part1 = + talloc_asprintf_append(q->mem_ctx, q->part1, + "%s = '%s',", name, esc_value); + } else { + q->part1 = + talloc_asprintf_append(q->mem_ctx, q->part1, "%s,", name); + q->part2 = + talloc_asprintf_append(q->mem_ctx, q->part2, "'%s',", + esc_value); + } + + SAFE_FREE(esc_value); + + return NT_STATUS_OK; +} + +#define config_value(data,name,default_value) \ + lp_parm_const_string(GLOBAL_SECTION_SNUM, data, name, default_value) + +static const char * config_value_write(const char *location, const char *name, const char *default_value) +{ + char const *v = NULL; + char const *swrite = NULL; + + v = lp_parm_const_string(GLOBAL_SECTION_SNUM, location, name, default_value); + + if (!v) + return NULL; + + swrite = strrchr(v, ':'); + + /* Default to the same field as read field */ + if (!swrite) + return v; + + swrite++; + + /* If the field is 0 chars long, we shouldn't write to it */ + if (!strlen(swrite) || !strcmp(swrite, "NULL")) + return NULL; + + /* Otherwise, use the additionally specified */ + return swrite; +} + +static const char * config_value_read(const char *location, const char *name, const char *default_value) +{ + char *v = NULL; + char *swrite; + + v = lp_parm_talloc_string(GLOBAL_SECTION_SNUM, location, name, default_value); + + if (!v) + return "NULL"; + + swrite = strrchr(v, ':'); + + /* If no write is specified, there are no problems */ + if (!swrite) { + if (strlen(v) == 0) + return "NULL"; + return (const char *)v; + } + + /* Otherwise, we have to cut the ':write_part' */ + *swrite = '\0'; + if (strlen(v) == 0) + return "NULL"; + + return (const char *)v; +} + +char *sql_account_query_select(const char *data, BOOL update, enum sql_search_field field, const char *value) +{ + const char *field_string; + char *query; + + switch(field) { + case SQL_SEARCH_NONE: + field_string = "'1'"; + value = "1"; + break; + + case SQL_SEARCH_USER_SID: + field_string = config_value_read(data, "user sid column", + CONFIG_USER_SID_DEFAULT); + break; + + case SQL_SEARCH_USER_NAME: + field_string = config_value_read(data, "username column", + CONFIG_USERNAME_DEFAULT); + break; + } + + asprintf(&query, + "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s WHERE %s = '%s'", + config_value_read(data, "logon time column", + CONFIG_LOGON_TIME_DEFAULT), + config_value_read(data, "logoff time column", + CONFIG_LOGOFF_TIME_DEFAULT), + config_value_read(data, "kickoff time column", + CONFIG_KICKOFF_TIME_DEFAULT), + config_value_read(data, "pass last set time column", + CONFIG_PASS_LAST_SET_TIME_DEFAULT), + config_value_read(data, "pass can change time column", + CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT), + config_value_read(data, "pass must change time column", + CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT), + config_value_read(data, "username column", + CONFIG_USERNAME_DEFAULT), + config_value_read(data, "domain column", + CONFIG_DOMAIN_DEFAULT), + config_value_read(data, "nt username column", + CONFIG_NT_USERNAME_DEFAULT), + config_value_read(data, "fullname column", + CONFIG_FULLNAME_DEFAULT), + config_value_read(data, "home dir column", + CONFIG_HOME_DIR_DEFAULT), + config_value_read(data, "dir drive column", + CONFIG_DIR_DRIVE_DEFAULT), + config_value_read(data, "logon script column", + CONFIG_LOGON_SCRIPT_DEFAULT), + config_value_read(data, "profile path column", + CONFIG_PROFILE_PATH_DEFAULT), + config_value_read(data, "acct desc column", + CONFIG_ACCT_DESC_DEFAULT), + config_value_read(data, "workstations column", + CONFIG_WORKSTATIONS_DEFAULT), + config_value_read(data, "unknown string column", + CONFIG_UNKNOWN_STR_DEFAULT), + config_value_read(data, "munged dial column", + CONFIG_MUNGED_DIAL_DEFAULT), + config_value_read(data, "user sid column", + CONFIG_USER_SID_DEFAULT), + config_value_read(data, "group sid column", + CONFIG_GROUP_SID_DEFAULT), + config_value_read(data, "lanman pass column", + CONFIG_LM_PW_DEFAULT), + config_value_read(data, "nt pass column", + CONFIG_NT_PW_DEFAULT), + config_value_read(data, "plain pass column", + CONFIG_PLAIN_PW_DEFAULT), + config_value_read(data, "acct ctrl column", + CONFIG_ACCT_CTRL_DEFAULT), + config_value_read(data, "unknown 3 column", + CONFIG_UNKNOWN_3_DEFAULT), + config_value_read(data, "logon divs column", + CONFIG_LOGON_DIVS_DEFAULT), + config_value_read(data, "hours len column", + CONFIG_HOURS_LEN_DEFAULT), + config_value_read(data, "bad password count column", + CONFIG_BAD_PASSWORD_COUNT_DEFAULT), + config_value_read(data, "logon count column", + CONFIG_LOGON_COUNT_DEFAULT), + config_value_read(data, "unknown 6 column", + CONFIG_UNKNOWN_6_DEFAULT), + config_value(data, "table", CONFIG_TABLE_DEFAULT), + field_string, value + ); + return query; +} + +char *sql_account_query_delete(const char *data, const char *esc) +{ + char *query; + + asprintf(&query, "DELETE FROM %s WHERE %s = '%s'", + config_value(data, "table", CONFIG_TABLE_DEFAULT), + config_value_read(data, "username column", + CONFIG_USERNAME_DEFAULT), esc); + return query; +} + +char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd, char isupdate) +{ + char *ret; + pstring temp; + pdb_sql_query query; + fstring sid_str; + + query.update = isupdate; + + /* I know this is somewhat overkill but only the talloc + * functions have asprint_append and the 'normal' asprintf + * is a GNU extension */ + query.mem_ctx = talloc_init("sql_query_update"); + query.part2 = talloc_asprintf(query.mem_ctx, "%s", ""); + if (query.update) { + query.part1 = + talloc_asprintf(query.mem_ctx, "UPDATE %s SET ", + config_value(location, "table", + CONFIG_TABLE_DEFAULT)); + } else { + query.part1 = + talloc_asprintf(query.mem_ctx, "INSERT INTO %s (", + config_value(location, "table", + CONFIG_TABLE_DEFAULT)); + } + + pdb_sql_int_field(&query, + config_value_write(location, "acct ctrl column", + CONFIG_ACCT_CTRL_DEFAULT), + pdb_get_acct_ctrl(newpwd)); + + if (pdb_get_init_flags(newpwd, PDB_LOGONTIME) != PDB_DEFAULT) { + pdb_sql_int_field(&query, + config_value_write(location, + "logon time column", + CONFIG_LOGON_TIME_DEFAULT), + pdb_get_logon_time(newpwd)); + } + + if (pdb_get_init_flags(newpwd, PDB_LOGOFFTIME) != PDB_DEFAULT) { + pdb_sql_int_field(&query, + config_value_write(location, + "logoff time column", + CONFIG_LOGOFF_TIME_DEFAULT), + pdb_get_logoff_time(newpwd)); + } + + if (pdb_get_init_flags(newpwd, PDB_KICKOFFTIME) != PDB_DEFAULT) { + pdb_sql_int_field(&query, + config_value_write(location, + "kickoff time column", + CONFIG_KICKOFF_TIME_DEFAULT), + pdb_get_kickoff_time(newpwd)); + } + + if (pdb_get_init_flags(newpwd, PDB_CANCHANGETIME) != PDB_DEFAULT) { + pdb_sql_int_field(&query, + config_value_write(location, + "pass can change time column", + CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT), + pdb_get_pass_can_change_time(newpwd)); + } + + if (pdb_get_init_flags(newpwd, PDB_MUSTCHANGETIME) != PDB_DEFAULT) { + pdb_sql_int_field(&query, + config_value_write(location, + "pass must change time column", + CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT), + pdb_get_pass_must_change_time(newpwd)); + } + + if (pdb_get_pass_last_set_time(newpwd)) { + pdb_sql_int_field(&query, + config_value_write(location, + "pass last set time column", + CONFIG_PASS_LAST_SET_TIME_DEFAULT), + pdb_get_pass_last_set_time(newpwd)); + } + + if (pdb_get_hours_len(newpwd)) { + pdb_sql_int_field(&query, + config_value_write(location, + "hours len column", + CONFIG_HOURS_LEN_DEFAULT), + pdb_get_hours_len(newpwd)); + } + + if (pdb_get_logon_divs(newpwd)) { + pdb_sql_int_field(&query, + config_value_write(location, + "logon divs column", + CONFIG_LOGON_DIVS_DEFAULT), + pdb_get_logon_divs(newpwd)); + } + + pdb_sql_string_field(&query, + config_value_write(location, "user sid column", + CONFIG_USER_SID_DEFAULT), + sid_to_string(sid_str, + pdb_get_user_sid(newpwd))); + + pdb_sql_string_field(&query, + config_value_write(location, "group sid column", + CONFIG_GROUP_SID_DEFAULT), + sid_to_string(sid_str, + pdb_get_group_sid(newpwd))); + + pdb_sql_string_field(&query, + config_value_write(location, "username column", + CONFIG_USERNAME_DEFAULT), + pdb_get_username(newpwd)); + + pdb_sql_string_field(&query, + config_value_write(location, "domain column", + CONFIG_DOMAIN_DEFAULT), + pdb_get_domain(newpwd)); + + pdb_sql_string_field(&query, + config_value_write(location, + "nt username column", + CONFIG_NT_USERNAME_DEFAULT), + pdb_get_nt_username(newpwd)); + + pdb_sql_string_field(&query, + config_value_write(location, "fullname column", + CONFIG_FULLNAME_DEFAULT), + pdb_get_fullname(newpwd)); + + pdb_sql_string_field(&query, + config_value_write(location, + "logon script column", + CONFIG_LOGON_SCRIPT_DEFAULT), + pdb_get_logon_script(newpwd)); + + pdb_sql_string_field(&query, + config_value_write(location, + "profile path column", + CONFIG_PROFILE_PATH_DEFAULT), + pdb_get_profile_path(newpwd)); + + pdb_sql_string_field(&query, + config_value_write(location, "dir drive column", + CONFIG_DIR_DRIVE_DEFAULT), + pdb_get_dir_drive(newpwd)); + + pdb_sql_string_field(&query, + config_value_write(location, "home dir column", + CONFIG_HOME_DIR_DEFAULT), + pdb_get_homedir(newpwd)); + + pdb_sql_string_field(&query, + config_value_write(location, + "workstations column", + CONFIG_WORKSTATIONS_DEFAULT), + pdb_get_workstations(newpwd)); + + pdb_sql_string_field(&query, + config_value_write(location, + "unknown string column", + CONFIG_UNKNOWN_STR_DEFAULT), + pdb_get_workstations(newpwd)); + + pdb_sethexpwd(temp, pdb_get_lanman_passwd(newpwd), + pdb_get_acct_ctrl(newpwd)); + pdb_sql_string_field(&query, + config_value_write(location, + "lanman pass column", + CONFIG_LM_PW_DEFAULT), temp); + + pdb_sethexpwd(temp, pdb_get_nt_passwd(newpwd), + pdb_get_acct_ctrl(newpwd)); + pdb_sql_string_field(&query, + config_value_write(location, "nt pass column", + CONFIG_NT_PW_DEFAULT), temp); + + if (query.update) { + query.part1[strlen(query.part1) - 1] = '\0'; + query.part1 = + talloc_asprintf_append(query.mem_ctx, query.part1, + " WHERE %s = '%s'", + config_value_read(location, + "user sid column", + CONFIG_USER_SID_DEFAULT), + sid_to_string(sid_str, pdb_get_user_sid (newpwd))); + } else { + query.part2[strlen(query.part2) - 1] = ')'; + query.part1[strlen(query.part1) - 1] = ')'; + query.part1 = + talloc_asprintf_append(query.mem_ctx, query.part1, + " VALUES (%s", query.part2); + } + + ret = strdup(query.part1); + talloc_destroy(query.mem_ctx); + return ret; +} + +BOOL sql_account_config_valid(const char *data) +{ + const char *sid_column, *username_column; + + sid_column = config_value_read(data, "user sid column", CONFIG_USER_SID_DEFAULT); + username_column = config_value_read(data, "username column", CONFIG_USERNAME_DEFAULT); + + if(!strcmp(sid_column,"NULL") || !strcmp(username_column, "NULL")) { + DEBUG(0,("Please specify both a valid 'user sid column' and a valid 'username column' in smb.conf\n")); + return False; + } + + return True; +} -- cgit From a9f8b0dccba776e43814971b6dc8901b1b719186 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 5 Jan 2004 20:24:21 +0000 Subject: fix inverted check using krb5_kt_resolve() and HAVE_MEMORY_KEYTAB; bug 912 (This used to be commit cca2afecd505881412df65c21c0389a0079cf023) --- source3/configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 9b87aa6296..c5cf9f1dbb 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2706,8 +2706,8 @@ if test x"$with_ads_support" != x"no"; then krb5_init_context(&context); if (krb5_kt_resolve(context, "MEMORY:", &keytab)) - exit(0); - exit(1); + exit(1); + exit(0); }], samba_cv_HAVE_MEMORY_KEYTAB=yes, samba_cv_HAVE_MEMORY_KEYTAB=no)]) -- cgit From 0aba157e7c6c8f6078950871ab5e3a0f89440229 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 5 Jan 2004 21:01:06 +0000 Subject: Fix from James Flemer to make HAVE_ATTR_LIST linked to HAVE_SYS_ATTRIBUTES_H to fix AIX compile. Jeremy. (This used to be commit 1d90cc2034c023755981a07a49c3d9958b60fb74) --- source3/lib/system.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/lib/system.c b/source3/lib/system.c index 2e95efec79..577f0b9a20 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -1321,7 +1321,7 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size) #endif } -#if defined(HAVE_ATTR_LIST) +#if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H) static char attr_buffer[ATTR_MAX_VALUELEN]; static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags) @@ -1393,7 +1393,7 @@ ssize_t sys_listxattr (const char *path, char *list, size_t size) { #if defined(HAVE_LISTXATTR) return listxattr(path, list, size); -#elif defined(HAVE_ATTR_LIST) +#elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H) return irix_attr_list(path, 0, list, size, 0); #else errno = ENOSYS; @@ -1405,7 +1405,7 @@ ssize_t sys_llistxattr (const char *path, char *list, size_t size) { #if defined(HAVE_LLISTXATTR) return llistxattr(path, list, size); -#elif defined(HAVE_ATTR_LIST) +#elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H) return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW); #else errno = ENOSYS; -- cgit From 29d86e5e9a0df6799e991a9b260294dc56f6a0b5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:15:33 +0000 Subject: (merge from 3.0) Based on patch by Petri Asikainen fix bug #387 and #330. This patch will change order how attributes are modified from: add, delete to: delete, add This is needed to update single valued attributes in Novell NDS and should not harm anyone else. (This used to be commit e925cae0f3846ea95633d38afd652e0f3d8acfb9) --- source3/lib/smbldap.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 944f60c689..e05d127d91 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -438,22 +438,23 @@ BOOL fetch_ldap_pw(char **dn, char** pw) the old value, should it exist. */ if ((newval != NULL) && (strlen(newval) > 0)) { - smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval); - } + if (existed) { + /* There has been no value before, so don't delete it. + * Here's a possible race: We might end up with + * duplicate attributes */ + /* By deleting exactly the value we found in the entry this + * should be race-free in the sense that the LDAP-Server will + * deny the complete operation if somebody changed the + * attribute behind our back. */ + /* This will also allow modifying single valued attributes + * in Novell NDS. In NDS you have to first remove attribute and then + * you could add new value */ + + smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval); + } - if (!existed) { - /* There has been no value before, so don't delete it. - Here's a possible race: We might end up with - duplicate attributes */ - return; + smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval); } - - /* By deleting exactly the value we found in the entry this - should be race-free in the sense that the LDAP-Server will - deny the complete operation if somebody changed the - attribute behind our back. */ - - smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval); } /********************************************************************** -- cgit From fc9892ba7d6d116896793ad83cf1b51aa15c97be Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:16:47 +0000 Subject: (merge from 3.0) Show the error message for failure to set the ldap password. (For 'ldap password sync = yes') Andrew Bartlett (This used to be commit ef5d2309c2252c9d6111738075f863b69b616722) --- source3/passdb/pdb_ldap.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 4d7c7791bd..a1ac042410 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1252,8 +1252,14 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, LDAP_EXOP_MODIFY_PASSWD, bv, NULL, NULL, &retoid, &retdata)) != LDAP_SUCCESS) { - DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n", - pdb_get_username(newpwd),ldap_err2string(rc))); + char *ld_error = NULL; + ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, + &ld_error); + DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n", + pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown")); + SAFE_FREE(ld_error); + ber_bvfree(bv); + return NT_STATUS_UNSUCCESSFUL; } else { DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd))); #ifdef DEBUG_PASSWORD -- cgit From 8dd0f9538cbe2765c5645086ade3e77010e7327d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:18:06 +0000 Subject: (merge from 3.0) Check the return value of string_to_sid in a few more places. (But string_to_sid also needs to be less permissive on what it thinks are valid sids...) Andrew Bartlett (This used to be commit 74ea8682e4b5c78f456cc9284e953e35e4146a8b) --- source3/passdb/pdb_ldap.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index a1ac042410..1f44f5ab60 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1693,7 +1693,11 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state, get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID))); return False; } - string_to_sid(&map->sid, temp); + + if (!string_to_sid(&map->sid, temp)) { + DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp)); + return False; + } if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp)) { @@ -1749,6 +1753,7 @@ static BOOL init_ldap_from_group(LDAP *ldap_struct, *mods = NULL; sid_to_string(tmp, &map->sid); + smbldap_make_mod(ldap_struct, existing, mods, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), tmp); pstr_sprintf(tmp, "%i", map->sid_name_use); @@ -2362,7 +2367,10 @@ and will risk BDCs having inconsistant SIDs\n")); get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), domain_sid_string)) { BOOL found_sid; - string_to_sid(&ldap_domain_sid, domain_sid_string); + if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) { + DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be read as a valid SID\n", domain_sid_string)); + return NT_STATUS_INVALID_PARAMETER; + } found_sid = secrets_fetch_domain_sid(ldap_state->domain_name, &secrets_domain_sid); if (!found_sid || !sid_equal(&secrets_domain_sid, &ldap_domain_sid)) { /* reset secrets.tdb sid */ -- cgit From 239c4da56ca0827e39de5bec0a590d63ee476b24 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:19:49 +0000 Subject: (merge from 3.0) Shutting down the connection closes outstanding sessions, so we don't need to do it twice... Amdrew Bartlett (This used to be commit 77b3515981ebe972a4c78e14b205d0c70a34b69f) --- source3/libsmb/trusts_util.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 2c6eb1b55a..7c1000b9a5 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -182,7 +182,6 @@ done: /* cleanup */ if (cli) { DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n")); - cli_nt_session_close( cli ); cli_shutdown( cli ); } -- cgit From 1ba7740fd61ff7e10e5efe6a9e4d2a8c669fc82e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:20:59 +0000 Subject: (merge from 3.0) Add the alignment required before all 2-byte quantities in NDR. Allows us to correctly parse plaintext netlogon calls with odd-length passwords Andrew Bartlett (This used to be commit 39d8a9e488eb31796e8e7eca42fe27f8218ce5d6) --- source3/rpc_parse/parse_net.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index 5df75fc5f6..89673dd0e3 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -1540,6 +1540,9 @@ BOOL net_io_q_sam_logon(const char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, if(!smb_io_sam_info("", &q_l->sam_id, ps, depth)) return False; + if(!prs_align_uint16(ps)) + return False; + if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level)) return False; -- cgit From 5cf546c4cd1f01e852587a2717182d8d399db90e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:22:00 +0000 Subject: (merge from 3.0) Refactor our authentication and authentication testing code. The next move will be to remove our password checking code from the SAM authentication backend, and into a file where other parts of samba can use it. The ntlm_auth changes provide for better use of common code. Andrew Bartlett (This used to be commit 0d97b10248347398fbee66767baac0c7adf6889d) --- source3/auth/auth_sam.c | 367 +++++++++++++++++++------------- source3/utils/ntlm_auth.c | 523 ++++++++++++++++------------------------------ 2 files changed, 400 insertions(+), 490 deletions(-) diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index 7352a9685b..04b587343a 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -141,96 +141,129 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, return (memcmp(value_from_encryption, client_response, 16) == 0); } -/**************************************************************************** - Do a specific test for an smb password being correct, given a smb_password and - the lanman and NT responses. -****************************************************************************/ - -static NTSTATUS sam_password_ok(const struct auth_context *auth_context, - TALLOC_CTX *mem_ctx, - SAM_ACCOUNT *sampass, - const auth_usersupplied_info *user_info, - DATA_BLOB *user_sess_key, - DATA_BLOB *lm_sess_key) +/** + * Check a challenge-response password against the value of the NT or + * LM password hash. + * + * @param mem_ctx talloc context + * @param challenge 8-byte challenge. If all zero, forces plaintext comparison + * @param nt_response 'unicode' NT response to the challenge, or unicode password + * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page + * @param username internal Samba username, for log messages + * @param client_username username the client used + * @param client_domain domain name the client used (may be mapped) + * @param nt_pw MD4 unicode password from our passdb or similar + * @param lm_pw LANMAN ASCII password from our passdb or similar + * @param user_sess_key User session key + * @param lm_sess_key LM session key (first 8 bytes of the LM hash) + */ + +static NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, + const DATA_BLOB *challenge, + const DATA_BLOB *lm_response, + const DATA_BLOB *nt_response, + const char *username, + const char *client_username, + const char *client_domain, + const uint8 *lm_pw, const uint8 *nt_pw, + DATA_BLOB *user_sess_key, + DATA_BLOB *lm_sess_key) { - uint16 acct_ctrl; - const uint8 *nt_pw, *lm_pw; - uint32 auth_flags; - - acct_ctrl = pdb_get_acct_ctrl(sampass); - if (acct_ctrl & ACB_PWNOTREQ) { - if (lp_null_passwords()) { - DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", pdb_get_username(sampass))); - return(NT_STATUS_OK); - } else { - DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", pdb_get_username(sampass))); - return(NT_STATUS_LOGON_FAILURE); - } + static const unsigned char zeros[8]; + if (nt_pw == NULL) { + DEBUG(3,("sam_password_ok: NO NT password stored for user %s.\n", + username)); } - auth_flags = user_info->auth_flags; + /* Check for cleartext netlogon. Used by Exchange 5.5. */ + if (challenge->length == sizeof(zeros) && + (memcmp(challenge->data, zeros, challenge->length) == 0 )) { - if (IS_SAM_DEFAULT(sampass, PDB_NTPASSWD)) { - DEBUG(3,("sam_password_ok: NO NT password stored for user %s.\n", - pdb_get_username(sampass))); - /* No return, we want to check the LM hash below in this case */ - auth_flags &= (~(AUTH_FLAG_NTLMv2_RESP | AUTH_FLAG_NTLM_RESP)); - } else { - /* Check for cleartext netlogon. Used by Exchange 5.5. */ - unsigned char zeros[8]; - - memset(zeros,'\0',sizeof(zeros)); - if (auth_context->challenge.length == sizeof(zeros) && - (memcmp(auth_context->challenge.data, zeros, auth_context->challenge.length) == 0 ) && - user_info->nt_resp.length) { - if ((nt_pw = pdb_get_nt_passwd(sampass)) != NULL) { - unsigned char pwhash[16]; - mdfour(pwhash, user_info->nt_resp.data, user_info->nt_resp.length); - if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) { - return NT_STATUS_OK; - } + DEBUG(4,("sam_password_ok: checking plaintext passwords for user %s\n", + username)); + if (nt_pw && nt_response->length) { + unsigned char pwhash[16]; + mdfour(pwhash, nt_response->data, nt_response->length); + if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(3,("sam_password_ok: NT (Unicode) plaintext password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + } else if (!lp_lanman_auth()) { + DEBUG(3,("sam_password_ok: (plaintext password check) LANMAN passwords NOT PERMITTED for user %s\n", + username)); + + } else if (lm_pw && lm_response->length) { + uchar dospwd[14]; + uchar p16[16]; + ZERO_STRUCT(dospwd); + + DEBUG(100, ("DOS password: %s\n")); + memcpy(dospwd, lm_response->data, MIN(lm_response->length, sizeof(dospwd))); + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ + E_P16((const unsigned char *)dospwd, p16); + + dump_data_pw("DOS password (first buffer)\n", dospwd, 14); + dump_data_pw("DOS password (wire DES hash)\n", p16, 16); + dump_data_pw("DOS password (passdb DES hash)\n", lm_pw, 16); + if (memcmp(p16, lm_pw, sizeof(p16)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(3,("sam_password_ok: LANMAN (ASCII) plaintext password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; } + } else { + DEBUG(3, ("Plaintext authentication for user %s attempted, but neither NT nor LM passwords available\n", username)); + return NT_STATUS_WRONG_PASSWORD; } } + + if (nt_response->length != 0 && nt_response->length < 24) { + DEBUG(2,("sam_password_ok: invalid NT password length (%lu) for user %s\n", + (unsigned long)nt_response->length, username)); + } - if (auth_flags & AUTH_FLAG_NTLMv2_RESP) { - nt_pw = pdb_get_nt_passwd(sampass); - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("sam_password_ok: Checking NTLMv2 password with domain [%s]\n", user_info->client_domain.str)); - if (smb_pwd_check_ntlmv2( &user_info->nt_resp, - nt_pw, &auth_context->challenge, - user_info->smb_name.str, - user_info->client_domain.str, - user_sess_key)) { - return NT_STATUS_OK; + if (nt_response->length >= 24 && nt_pw) { + if (nt_response->length > 24) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("sam_password_ok: Checking NTLMv2 password with domain [%s]\n", client_domain)); + if (smb_pwd_check_ntlmv2( nt_response, + nt_pw, challenge, + client_username, + client_domain, + user_sess_key)) { + return NT_STATUS_OK; + } + + DEBUG(4,("sam_password_ok: Checking NTLMv2 password without a domain\n")); + if (smb_pwd_check_ntlmv2( nt_response, + nt_pw, challenge, + client_username, + "", + user_sess_key)) { + return NT_STATUS_OK; + } else { + DEBUG(3,("sam_password_ok: NTLMv2 password check failed\n")); + return NT_STATUS_WRONG_PASSWORD; + } } - DEBUG(4,("sam_password_ok: Checking NTLMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2( &user_info->nt_resp, - nt_pw, &auth_context->challenge, - user_info->smb_name.str, - "", - user_sess_key)) { - return NT_STATUS_OK; - } else { - DEBUG(3,("sam_password_ok: NTLMv2 password check failed\n")); - return NT_STATUS_WRONG_PASSWORD; - } - } else if (auth_flags & AUTH_FLAG_NTLM_RESP) { if (lp_ntlm_auth()) { - nt_pw = pdb_get_nt_passwd(sampass); /* We have the NT MD4 hash challenge available - see if we can use it (ie. does it exist in the smbpasswd file). */ DEBUG(4,("sam_password_ok: Checking NT MD4 password\n")); - if (smb_pwd_check_ntlmv1(&user_info->nt_resp, - nt_pw, &auth_context->challenge, + if (smb_pwd_check_ntlmv1(nt_response, + nt_pw, challenge, user_sess_key)) { /* The LM session key for this response is not very secure, so use it only if we otherwise allow LM authentication */ - lm_pw = pdb_get_lanman_passwd(sampass); if (lp_lanman_auth() && lm_pw) { uint8 first_8_lm_hash[16]; @@ -240,104 +273,142 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, } return NT_STATUS_OK; } else { - DEBUG(3,("sam_password_ok: NT MD4 password check failed for user %s\n",pdb_get_username(sampass))); + DEBUG(3,("sam_password_ok: NT MD4 password check failed for user %s\n", + username)); return NT_STATUS_WRONG_PASSWORD; } } else { - DEBUG(2,("sam_password_ok: NTLMv1 passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass))); + DEBUG(2,("sam_password_ok: NTLMv1 passwords NOT PERMITTED for user %s\n", + username)); /* no return, becouse we might pick up LMv2 in the LM field */ } } - if (auth_flags & AUTH_FLAG_LM_RESP) { - if (user_info->lm_resp.length != 24) { - DEBUG(2,("sam_password_ok: invalid LanMan password length (%lu) for user %s\n", - (unsigned long)user_info->nt_resp.length, pdb_get_username(sampass))); - } + if (lm_response->length == 0) { + DEBUG(3,("sam_password_ok: NEITHER LanMan nor NT password supplied for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (lm_response->length < 24) { + DEBUG(2,("sam_password_ok: invalid LanMan password length (%lu) for user %s\n", + (unsigned long)nt_response->length, username)); + return NT_STATUS_WRONG_PASSWORD; + } - if (!lp_lanman_auth()) { - DEBUG(3,("sam_password_ok: Lanman passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass))); - } else if (IS_SAM_DEFAULT(sampass, PDB_LMPASSWD)) { - DEBUG(3,("sam_password_ok: NO LanMan password set for user %s (and no NT password supplied)\n",pdb_get_username(sampass))); - } else { - lm_pw = pdb_get_lanman_passwd(sampass); - - DEBUG(4,("sam_password_ok: Checking LM password\n")); - if (smb_pwd_check_ntlmv1(&user_info->lm_resp, - lm_pw, &auth_context->challenge, - NULL)) { + if (!lp_lanman_auth()) { + DEBUG(3,("sam_password_ok: Lanman passwords NOT PERMITTED for user %s\n", + username)); + } else if (!lm_pw) { + DEBUG(3,("sam_password_ok: NO LanMan password set for user %s (and no NT password supplied)\n", + username)); + } else { + DEBUG(4,("sam_password_ok: Checking LM password\n")); + if (smb_pwd_check_ntlmv1(lm_response, + lm_pw, challenge, + NULL)) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *user_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + return NT_STATUS_OK; + } + } + + if (!nt_pw) { + DEBUG(4,("sam_password_ok: LM password check failed for user, no NT password %s\n",username)); + return NT_STATUS_WRONG_PASSWORD; + } + + /* This is for 'LMv2' authentication. almost NTLMv2 but limited to 24 bytes. + - related to Win9X, legacy NAS pass-though authentication + */ + DEBUG(4,("sam_password_ok: Checking LMv2 password with domain %s\n", client_domain)); + if (smb_pwd_check_ntlmv2( lm_response, + nt_pw, challenge, + client_username, + client_domain, + NULL)) { + return NT_STATUS_OK; + } + + DEBUG(4,("sam_password_ok: Checking LMv2 password without a domain\n")); + if (smb_pwd_check_ntlmv2( lm_response, + nt_pw, challenge, + client_username, + "", + NULL)) { + return NT_STATUS_OK; + } + + /* Apparently NT accepts NT responses in the LM field + - I think this is related to Win9X pass-though authentication + */ + DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM field\n")); + if (lp_ntlm_auth()) { + if (smb_pwd_check_ntlmv1(lm_response, + nt_pw, challenge, + NULL)) { + /* The session key for this response is still very odd. + It not very secure, so use it only if we otherwise + allow LM authentication */ + + if (lp_lanman_auth() && lm_pw) { uint8 first_8_lm_hash[16]; memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); *user_sess_key = data_blob(first_8_lm_hash, 16); *lm_sess_key = data_blob(first_8_lm_hash, 16); - return NT_STATUS_OK; } - } - - if (IS_SAM_DEFAULT(sampass, PDB_NTPASSWD)) { - DEBUG(4,("sam_password_ok: LM password check failed for user, no NT password %s\n",pdb_get_username(sampass))); - return NT_STATUS_WRONG_PASSWORD; - } - - nt_pw = pdb_get_nt_passwd(sampass); - - /* This is for 'LMv2' authentication. almost NTLMv2 but limited to 24 bytes. - - related to Win9X, legacy NAS pass-though authentication - */ - DEBUG(4,("sam_password_ok: Checking LMv2 password with domain %s\n", user_info->client_domain.str)); - if (smb_pwd_check_ntlmv2( &user_info->lm_resp, - nt_pw, &auth_context->challenge, - user_info->smb_name.str, - user_info->client_domain.str, - NULL)) { return NT_STATUS_OK; } + DEBUG(3,("sam_password_ok: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username)); + } else { + DEBUG(3,("sam_password_ok: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username)); + } + return NT_STATUS_WRONG_PASSWORD; +} - DEBUG(4,("sam_password_ok: Checking LMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2( &user_info->lm_resp, - nt_pw, &auth_context->challenge, - user_info->smb_name.str, - "", - NULL)) { - return NT_STATUS_OK; - } +/**************************************************************************** + Do a specific test for an smb password being correct, given a smb_password and + the lanman and NT responses. +****************************************************************************/ - /* Apparently NT accepts NT responses in the LM field - - I think this is related to Win9X pass-though authentication - */ - DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM field\n")); - if (lp_ntlm_auth()) { - if (smb_pwd_check_ntlmv1(&user_info->lm_resp, - nt_pw, &auth_context->challenge, - NULL)) { - /* The session key for this response is still very odd. - It not very secure, so use it only if we otherwise - allow LM authentication */ - lm_pw = pdb_get_lanman_passwd(sampass); - - if (lp_lanman_auth() && lm_pw) { - uint8 first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - *user_sess_key = data_blob(first_8_lm_hash, 16); - *lm_sess_key = data_blob(first_8_lm_hash, 16); - } - return NT_STATUS_OK; - } - DEBUG(3,("sam_password_ok: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",pdb_get_username(sampass))); - return NT_STATUS_WRONG_PASSWORD; +static NTSTATUS sam_password_ok(const struct auth_context *auth_context, + TALLOC_CTX *mem_ctx, + SAM_ACCOUNT *sampass, + const auth_usersupplied_info *user_info, + DATA_BLOB *user_sess_key, + DATA_BLOB *lm_sess_key) +{ + uint16 acct_ctrl; + const uint8 *lm_pw, *nt_pw; + const char *username = pdb_get_username(sampass); + + acct_ctrl = pdb_get_acct_ctrl(sampass); + if (acct_ctrl & ACB_PWNOTREQ) { + if (lp_null_passwords()) { + DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", username)); + return NT_STATUS_OK; } else { - DEBUG(3,("sam_password_ok: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",pdb_get_username(sampass))); - return NT_STATUS_WRONG_PASSWORD; - } + DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", username)); + return NT_STATUS_LOGON_FAILURE; + } } - - /* Should not be reached, but if they send nothing... */ - DEBUG(3,("sam_password_ok: NEITHER LanMan nor NT password supplied for user %s\n",pdb_get_username(sampass))); - return NT_STATUS_WRONG_PASSWORD; + + lm_pw = pdb_get_lanman_passwd(sampass); + nt_pw = pdb_get_nt_passwd(sampass); + + return ntlm_password_check(mem_ctx, &auth_context->challenge, + &user_info->lm_resp, &user_info->nt_resp, + username, + user_info->smb_name.str, + user_info->client_domain.str, + lm_pw, nt_pw, user_sess_key, lm_sess_key); } + /**************************************************************************** Do a specific test for a SAM_ACCOUNT being vaild for this connection (ie not disabled, expired and the like). diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 132134fd9d..c15a6e8758 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -38,6 +38,14 @@ enum stdio_helper_mode { NUM_HELPER_MODES }; +enum ntlm_break { + BREAK_NONE, + BREAK_LM, + BREAK_NT, + NO_LM, + NO_NT +}; + typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode, char *buf, int length); @@ -1216,72 +1224,11 @@ static DATA_BLOB get_challenge(void) return chal; } -/* - * Test LM authentication, no NT response supplied - */ - -static BOOL test_lm(void) -{ - NTSTATUS nt_status; - uint32 flags = 0; - DATA_BLOB lm_response = data_blob(NULL, 24); - - uchar lm_key[8]; - uchar nt_key[16]; - uchar lm_hash[16]; - DATA_BLOB chall = get_challenge(); - char *error_string; - - ZERO_STRUCT(lm_key); - ZERO_STRUCT(nt_key); - - flags |= WBFLAG_PAM_LMKEY; - flags |= WBFLAG_PAM_NTKEY; - - SMBencrypt(opt_password, chall.data, lm_response.data); - E_deshash(opt_password, lm_hash); - - nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, - &chall, - &lm_response, - NULL, - flags, - lm_key, - nt_key, - &error_string); - - data_blob_free(&lm_response); - - if (!NT_STATUS_IS_OK(nt_status)) { - d_printf("%s (0x%x)\n", - error_string, - NT_STATUS_V(nt_status)); - return False; - } - - if (memcmp(lm_hash, lm_key, - sizeof(lm_key)) != 0) { - DEBUG(1, ("LM Key does not match expectations!\n")); - DEBUG(1, ("lm_key:\n")); - dump_data(1, (const char *)lm_key, 8); - DEBUG(1, ("expected:\n")); - dump_data(1, (const char *)lm_hash, 8); - } - if (memcmp(lm_hash, nt_key, 8) != 0) { - DEBUG(1, ("Session Key (first 8, lm hash) does not match expectations!\n")); - DEBUG(1, ("nt_key:\n")); - dump_data(1, (const char *)nt_key, 8); - DEBUG(1, ("expected:\n")); - dump_data(1, (const char *)lm_hash, 8); - } - return True; -} - /* * Test the normal 'LM and NTLM' combination */ -static BOOL test_lm_ntlm(void) +static BOOL test_lm_ntlm_broken(enum ntlm_break break_which) { BOOL pass = True; NTSTATUS nt_status; @@ -1311,6 +1258,23 @@ static BOOL test_lm_ntlm(void) E_md4hash(opt_password, nt_hash); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + switch (break_which) { + case BREAK_NONE: + break; + case BREAK_LM: + lm_response.data[0]++; + break; + case BREAK_NT: + nt_response.data[0]++; + break; + case NO_LM: + data_blob_free(&lm_response); + break; + case NO_NT: + data_blob_free(&nt_response); + break; + } + nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, &chall, @@ -1328,7 +1292,7 @@ static BOOL test_lm_ntlm(void) error_string, NT_STATUS_V(nt_status)); SAFE_FREE(error_string); - return False; + return break_which == BREAK_NT; } if (memcmp(lm_hash, lm_key, @@ -1340,88 +1304,48 @@ static BOOL test_lm_ntlm(void) dump_data(1, (const char *)lm_hash, 8); pass = False; } - if (memcmp(session_key.data, nt_key, - sizeof(nt_key)) != 0) { - DEBUG(1, ("NT Session Key does not match expectations!\n")); - DEBUG(1, ("nt_key:\n")); - dump_data(1, (const char *)nt_key, 16); - DEBUG(1, ("expected:\n")); - dump_data(1, (const char *)session_key.data, session_key.length); - pass = False; + + if (break_which == NO_NT) { + if (memcmp(lm_hash, nt_key, + 8) != 0) { + DEBUG(1, ("NT Session Key does not match expectations (should be LM hash)!\n")); + DEBUG(1, ("nt_key:\n")); + dump_data(1, (const char *)nt_key, sizeof(nt_key)); + DEBUG(1, ("expected:\n")); + dump_data(1, (const char *)lm_hash, sizeof(lm_hash)); + pass = False; + } + } else { + if (memcmp(session_key.data, nt_key, + sizeof(nt_key)) != 0) { + DEBUG(1, ("NT Session Key does not match expectations!\n")); + DEBUG(1, ("nt_key:\n")); + dump_data(1, (const char *)nt_key, 16); + DEBUG(1, ("expected:\n")); + dump_data(1, (const char *)session_key.data, session_key.length); + pass = False; + } } return pass; } /* - * Test the NTLM response only, no LM. + * Test LM authentication, no NT response supplied */ -static BOOL test_ntlm(void) +static BOOL test_lm(void) { - BOOL pass = True; - NTSTATUS nt_status; - uint32 flags = 0; - DATA_BLOB nt_response = data_blob(NULL, 24); - DATA_BLOB session_key = data_blob(NULL, 16); - - char lm_key[8]; - char nt_key[16]; - char lm_hash[16]; - char nt_hash[16]; - DATA_BLOB chall = get_challenge(); - char *error_string; - - ZERO_STRUCT(lm_key); - ZERO_STRUCT(nt_key); - flags |= WBFLAG_PAM_LMKEY; - flags |= WBFLAG_PAM_NTKEY; - - SMBNTencrypt(opt_password,chall.data,nt_response.data); - E_md4hash(opt_password, (unsigned char *)nt_hash); - SMBsesskeygen_ntv1((const unsigned char *)nt_hash, NULL, session_key.data); - - E_deshash(opt_password, (unsigned char *)lm_hash); - - nt_status = contact_winbind_auth_crap(opt_username, opt_domain, - opt_workstation, - &chall, - NULL, - &nt_response, - flags, - (unsigned char *)lm_key, - (unsigned char *)nt_key, - &error_string); - - data_blob_free(&nt_response); + return test_lm_ntlm_broken(NO_NT); +} - if (!NT_STATUS_IS_OK(nt_status)) { - d_printf("%s (0x%x)\n", - error_string, - NT_STATUS_V(nt_status)); - SAFE_FREE(error_string); - return False; - } +/* + * Test the NTLM response only, no LM. + */ - if (memcmp(lm_hash, lm_key, - sizeof(lm_key)) != 0) { - DEBUG(1, ("LM Key does not match expectations!\n")); - DEBUG(1, ("lm_key:\n")); - dump_data(1, lm_key, 8); - DEBUG(1, ("expected:\n")); - dump_data(1, lm_hash, 8); - pass = False; - } - if (memcmp(session_key.data, nt_key, - sizeof(nt_key)) != 0) { - DEBUG(1, ("NT Session Key does not match expectations!\n")); - DEBUG(1, ("nt_key:\n")); - dump_data(1, nt_key, 16); - DEBUG(1, ("expected:\n")); - dump_data(1, (const char *)session_key.data, session_key.length); - pass = False; - } - return pass; +static BOOL test_ntlm(void) +{ + return test_lm_ntlm_broken(NO_LM); } /* @@ -1565,15 +1489,16 @@ static BOOL test_ntlm_in_both(void) } /* - * Test the NTLMv2 response only + * Test the NTLMv2 and LMv2 responses */ -static BOOL test_ntlmv2(void) +static BOOL test_lmv2_ntlmv2_broken(enum ntlm_break break_which) { BOOL pass = True; NTSTATUS nt_status; uint32 flags = 0; DATA_BLOB ntlmv2_response = data_blob(NULL, 0); + DATA_BLOB lmv2_response = data_blob(NULL, 0); DATA_BLOB nt_session_key = data_blob(NULL, 0); DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain()); @@ -1587,23 +1512,41 @@ static BOOL test_ntlmv2(void) if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall, &names_blob, - NULL, &ntlmv2_response, + &lmv2_response, &ntlmv2_response, &nt_session_key)) { data_blob_free(&names_blob); return False; } data_blob_free(&names_blob); + switch (break_which) { + case BREAK_NONE: + break; + case BREAK_LM: + lmv2_response.data[0]++; + break; + case BREAK_NT: + ntlmv2_response.data[0]++; + break; + case NO_LM: + data_blob_free(&lmv2_response); + break; + case NO_NT: + data_blob_free(&ntlmv2_response); + break; + } + nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, &chall, - NULL, + &lmv2_response, &ntlmv2_response, flags, NULL, nt_key, &error_string); + data_blob_free(&lmv2_response); data_blob_free(&ntlmv2_response); if (!NT_STATUS_IS_OK(nt_status)) { @@ -1611,10 +1554,10 @@ static BOOL test_ntlmv2(void) error_string, NT_STATUS_V(nt_status)); SAFE_FREE(error_string); - return False; + return break_which == BREAK_NT; } - if (memcmp(nt_session_key.data, nt_key, + if (break_which != NO_NT && break_which != BREAK_NT && memcmp(nt_session_key.data, nt_key, sizeof(nt_key)) != 0) { DEBUG(1, ("NT Session Key does not match expectations!\n")); DEBUG(1, ("nt_key:\n")); @@ -1632,62 +1575,7 @@ static BOOL test_ntlmv2(void) static BOOL test_lmv2_ntlmv2(void) { - BOOL pass = True; - NTSTATUS nt_status; - uint32 flags = 0; - DATA_BLOB ntlmv2_response = data_blob(NULL, 0); - DATA_BLOB lmv2_response = data_blob(NULL, 0); - DATA_BLOB nt_session_key = data_blob(NULL, 0); - DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain()); - - uchar nt_key[16]; - DATA_BLOB chall = get_challenge(); - char *error_string; - - ZERO_STRUCT(nt_key); - - flags |= WBFLAG_PAM_NTKEY; - - if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall, - &names_blob, - &lmv2_response, &ntlmv2_response, - &nt_session_key)) { - data_blob_free(&names_blob); - return False; - } - data_blob_free(&names_blob); - - nt_status = contact_winbind_auth_crap(opt_username, opt_domain, - opt_workstation, - &chall, - &lmv2_response, - &ntlmv2_response, - flags, - NULL, - nt_key, - &error_string); - - data_blob_free(&lmv2_response); - data_blob_free(&ntlmv2_response); - - if (!NT_STATUS_IS_OK(nt_status)) { - d_printf("%s (0x%x)\n", - error_string, - NT_STATUS_V(nt_status)); - SAFE_FREE(error_string); - return False; - } - - if (memcmp(nt_session_key.data, nt_key, - sizeof(nt_key)) != 0) { - DEBUG(1, ("NT Session Key does not match expectations!\n")); - DEBUG(1, ("nt_key:\n")); - dump_data(1, (const char *)nt_key, 16); - DEBUG(1, ("expected:\n")); - dump_data(1, (const char *)nt_session_key.data, nt_session_key.length); - pass = False; - } - return pass; + return test_lmv2_ntlmv2_broken(BREAK_NONE); } /* @@ -1696,200 +1584,145 @@ static BOOL test_lmv2_ntlmv2(void) static BOOL test_lmv2(void) { - BOOL pass = True; - NTSTATUS nt_status; - uint32 flags = 0; - DATA_BLOB lmv2_response = data_blob(NULL, 0); - - DATA_BLOB chall = get_challenge(); - char *error_string; - - if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall, - NULL, - &lmv2_response, NULL, - NULL)) { - return False; - } - - nt_status = contact_winbind_auth_crap(opt_username, opt_domain, - opt_workstation, - &chall, - &lmv2_response, - NULL, - flags, - NULL, - NULL, - &error_string); - - data_blob_free(&lmv2_response); - - if (!NT_STATUS_IS_OK(nt_status)) { - d_printf("%s (0x%x)\n", - error_string, - NT_STATUS_V(nt_status)); - SAFE_FREE(error_string); - return False; - } - - return pass; + return test_lmv2_ntlmv2_broken(NO_NT); } /* - * Test the normal 'LM and NTLM' combination but deliberately break one + * Test the NTLMv2 response only */ -static BOOL test_ntlm_broken(BOOL break_lm) +static BOOL test_ntlmv2(void) { - BOOL pass = True; - NTSTATUS nt_status; - uint32 flags = 0; - DATA_BLOB lm_response = data_blob(NULL, 24); - DATA_BLOB nt_response = data_blob(NULL, 24); - DATA_BLOB session_key = data_blob(NULL, 16); - - uchar lm_key[8]; - uchar nt_key[16]; - uchar lm_hash[16]; - uchar nt_hash[16]; - DATA_BLOB chall = get_challenge(); - char *error_string; - - ZERO_STRUCT(lm_key); - ZERO_STRUCT(nt_key); - - flags |= WBFLAG_PAM_LMKEY; - flags |= WBFLAG_PAM_NTKEY; - - SMBencrypt(opt_password,chall.data,lm_response.data); - E_deshash(opt_password, lm_hash); - - SMBNTencrypt(opt_password,chall.data,nt_response.data); - - E_md4hash(opt_password, nt_hash); - SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); - - if (break_lm) - lm_response.data[0]++; - else - nt_response.data[0]++; - - nt_status = contact_winbind_auth_crap(opt_username, opt_domain, - opt_workstation, - &chall, - &lm_response, - &nt_response, - flags, - lm_key, - nt_key, - &error_string); - - data_blob_free(&lm_response); - - if (!NT_STATUS_IS_OK(nt_status)) { - d_printf("%s (0x%x)\n", - error_string, - NT_STATUS_V(nt_status)); - SAFE_FREE(error_string); - return False; - } + return test_lmv2_ntlmv2_broken(NO_LM); +} - if (memcmp(lm_hash, lm_key, - sizeof(lm_key)) != 0) { - DEBUG(1, ("LM Key does not match expectations!\n")); - DEBUG(1, ("lm_key:\n")); - dump_data(1, (const char *)lm_key, 8); - DEBUG(1, ("expected:\n")); - dump_data(1, (const char *)lm_hash, 8); - pass = False; - } - if (memcmp(session_key.data, nt_key, - sizeof(nt_key)) != 0) { - DEBUG(1, ("NT Session Key does not match expectations!\n")); - DEBUG(1, ("nt_key:\n")); - dump_data(1, (const char *)nt_key, 16); - DEBUG(1, ("expected:\n")); - dump_data(1, (const char *)session_key.data, session_key.length); - pass = False; - } - return pass; +static BOOL test_lm_ntlm(void) +{ + return test_lm_ntlm_broken(BREAK_NONE); } static BOOL test_ntlm_lm_broken(void) { - return test_ntlm_broken(True); + return test_lm_ntlm_broken(BREAK_LM); } static BOOL test_ntlm_ntlm_broken(void) { - return test_ntlm_broken(False); + return test_lm_ntlm_broken(BREAK_NT); } -static BOOL test_ntlmv2_broken(BOOL break_lmv2) +static BOOL test_ntlmv2_lmv2_broken(void) +{ + return test_lmv2_ntlmv2_broken(BREAK_LM); +} + +static BOOL test_ntlmv2_ntlmv2_broken(void) +{ + return test_lmv2_ntlmv2_broken(BREAK_NT); +} + +static BOOL test_plaintext(enum ntlm_break break_which) { - BOOL pass = True; NTSTATUS nt_status; uint32 flags = 0; - DATA_BLOB ntlmv2_response = data_blob(NULL, 0); - DATA_BLOB lmv2_response = data_blob(NULL, 0); - DATA_BLOB nt_session_key = data_blob(NULL, 0); - DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain()); + DATA_BLOB nt_response = data_blob(NULL, 0); + DATA_BLOB lm_response = data_blob(NULL, 0); + char *password; uchar nt_key[16]; - DATA_BLOB chall = get_challenge(); + uchar lm_key[16]; + static const uchar zeros[8]; + DATA_BLOB chall = data_blob(zeros, sizeof(zeros)); char *error_string; ZERO_STRUCT(nt_key); flags |= WBFLAG_PAM_NTKEY; - - if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall, - &names_blob, - &lmv2_response, &ntlmv2_response, - &nt_session_key)) { - data_blob_free(&names_blob); - return False; + flags |= WBFLAG_PAM_LMKEY; + + if ((push_ucs2_allocate((smb_ucs2_t **)&nt_response.data, opt_password)) == -1) { + DEBUG(0, ("push_ucs2_allocate failed!\n")); + exit(1); } - data_blob_free(&names_blob); - /* Heh - this should break the appropriate password hash nicely! */ + nt_response.length = strlen_w(((void *)nt_response.data))*sizeof(smb_ucs2_t); - if (break_lmv2) - lmv2_response.data[0]++; - else - ntlmv2_response.data[0]++; + password = strdup_upper(opt_password); + + if ((convert_string_allocate(NULL, CH_UNIX, + CH_DOS, password, + strlen(password)+1, + (void**)&lm_response.data)) == -1) { + DEBUG(0, ("push_ascii_allocate failed!\n")); + exit(1); + } + + SAFE_FREE(password); + + lm_response.length = strlen(lm_response.data); + + switch (break_which) { + case BREAK_NONE: + break; + case BREAK_LM: + lm_response.data[0]++; + break; + case BREAK_NT: + nt_response.data[0]++; + break; + case NO_LM: + SAFE_FREE(lm_response.data); + lm_response.length = 0; + break; + case NO_NT: + SAFE_FREE(nt_response.data); + nt_response.length = 0; + break; + } nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, &chall, - &lmv2_response, - &ntlmv2_response, + &lm_response, + &nt_response, flags, - NULL, + lm_key, nt_key, &error_string); - data_blob_free(&lmv2_response); - data_blob_free(&ntlmv2_response); + SAFE_FREE(nt_response.data); + SAFE_FREE(lm_response.data); + data_blob_free(&chall); if (!NT_STATUS_IS_OK(nt_status)) { d_printf("%s (0x%x)\n", error_string, NT_STATUS_V(nt_status)); SAFE_FREE(error_string); - return False; + return break_which == BREAK_NT; } - return pass; + return break_which != BREAK_NT; } -static BOOL test_ntlmv2_lmv2_broken(void) -{ - return test_ntlmv2_broken(True); +static BOOL test_plaintext_none_broken(void) { + return test_plaintext(BREAK_NONE); } -static BOOL test_ntlmv2_ntlmv2_broken(void) -{ - return test_ntlmv2_broken(False); +static BOOL test_plaintext_lm_broken(void) { + return test_plaintext(BREAK_LM); +} + +static BOOL test_plaintext_nt_broken(void) { + return test_plaintext(BREAK_NT); +} + +static BOOL test_plaintext_nt_only(void) { + return test_plaintext(NO_LM); +} + +static BOOL test_plaintext_lm_only(void) { + return test_plaintext(NO_NT); } /* @@ -1903,7 +1736,8 @@ static BOOL test_ntlmv2_ntlmv2_broken(void) - NTLMv2 - NTLMv2 and LMv2 - LMv2 - + - plaintext tests (in challenge-response feilds) + check we get the correct session key in each case check what values we get for the LM session key @@ -1924,7 +1758,12 @@ struct ntlm_tests { {test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken"}, {test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken"}, {test_ntlm_lm_broken, "NTLM and LM, LM broken"}, - {test_ntlm_ntlm_broken, "NTLM and LM, NTLM broken"} + {test_ntlm_ntlm_broken, "NTLM and LM, NTLM broken"}, + {test_plaintext_none_broken, "Plaintext"}, + {test_plaintext_lm_broken, "Plaintext LM broken"}, + {test_plaintext_nt_broken, "Plaintext NT broken"}, + {test_plaintext_nt_only, "Plaintext NT only"}, + {test_plaintext_lm_only, "Plaintext LM only"} }; static BOOL diagnose_ntlm_auth(void) -- cgit From ba82ad14c6ef43551b99e2a3abdfd434e1810339 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:23:59 +0000 Subject: (merge from 3.0) Move our basic password checking code from inside the authentication subsystem into a seperate file - ntlm_check.c. This allows us to call these routines from ntlm_auth. The purpose of this exercise is to allow ntlm_auth (when operating as an NTLMSSP server) to avoid talking to winbind. This should allow for easier debugging. ntlm_auth itself has been reorgainised, so as to share more code between the SPNEGO-wrapped and 'raw' NTLMSSP modes. A new 'client' NTLMSSP mode has been added, for use with a Cyrus-SASL module I am writing (based on vl's work) Andrew Bartlett (This used to be commit 2f196bb31ac83cf7922583063c74a5f679ca5be7) --- source3/Makefile.in | 3 +- source3/auth/auth_sam.c | 346 +--------------------------------------- source3/libsmb/ntlm_check.c | 377 ++++++++++++++++++++++++++++++++++++++++++++ source3/utils/ntlm_auth.c | 308 +++++++++++++++++++++++++++++------- 4 files changed, 634 insertions(+), 400 deletions(-) create mode 100644 source3/libsmb/ntlm_check.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 042f424861..d89c2c3481 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -216,7 +216,8 @@ SECRETS_OBJ = passdb/secrets.o LIBNMB_OBJ = libsmb/unexpected.o libsmb/namecache.o libsmb/nmblib.o \ libsmb/namequery.o libsmb/conncache.o -LIBSAMBA_OBJ = libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o libsmb/ntlmssp.o libsmb/ntlmssp_parse.o libsmb/ntlmssp_sign.o +LIBSAMBA_OBJ = libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o libsmb/ntlm_check.o \ + libsmb/ntlmssp.o libsmb/ntlmssp_parse.o libsmb/ntlmssp_sign.o LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clikrb5.o libsmb/clispnego.o libsmb/asn1.o \ diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index 04b587343a..ebb1e3d861 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -3,7 +3,7 @@ Password and authentication handling Copyright (C) Andrew Tridgell 1992-2000 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Andrew Bartlett 2001 + Copyright (C) Andrew Bartlett 2001-2003 Copyright (C) Gerald Carter 2003 This program is free software; you can redistribute it and/or modify @@ -26,350 +26,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -/**************************************************************************** - Core of smb password checking routine. -****************************************************************************/ - -static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, - const uchar *part_passwd, - const DATA_BLOB *sec_blob, - DATA_BLOB *user_sess_key) -{ - /* Finish the encryption of part_passwd. */ - uchar p24[24]; - - if (part_passwd == NULL) { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always false ! */ - return False; - } - - if (sec_blob->length != 8) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", (unsigned long)sec_blob->length)); - return False; - } - - if (nt_response->length != 24) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", (unsigned long)nt_response->length)); - return False; - } - - SMBOWFencrypt(part_passwd, sec_blob->data, p24); - if (user_sess_key != NULL) { - *user_sess_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key->data); - } - - - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, part_passwd, 16); - DEBUGADD(100,("Password from client was |\n")); - dump_data(100, nt_response->data, nt_response->length); - DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, sec_blob->data, sec_blob->length); - DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, p24, 24); -#endif - return (memcmp(p24, nt_response->data, 24) == 0); -} - -/**************************************************************************** - Core of smb password checking routine. (NTLMv2, LMv2) - Note: The same code works with both NTLMv2 and LMv2. -****************************************************************************/ - -static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, - const uchar *part_passwd, - const DATA_BLOB *sec_blob, - const char *user, const char *domain, - DATA_BLOB *user_sess_key) -{ - /* Finish the encryption of part_passwd. */ - uchar kr[16]; - uchar value_from_encryption[16]; - uchar client_response[16]; - DATA_BLOB client_key_data; - - if (part_passwd == NULL) { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always False */ - return False; - } - - if (ntv2_response->length < 24) { - /* We MUST have more than 16 bytes, or the stuff below will go - crazy. No known implementation sends less than the 24 bytes - for LMv2, let alone NTLMv2. */ - DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", - (unsigned long)ntv2_response->length)); - return False; - } - - client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16); - /* - todo: should we be checking this for anything? We can't for LMv2, - but for NTLMv2 it is meant to contain the current time etc. - */ - - memcpy(client_response, ntv2_response->data, sizeof(client_response)); - - if (!ntv2_owf_gen(part_passwd, user, domain, kr)) { - return False; - } - - SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); - if (user_sess_key != NULL) { - *user_sess_key = data_blob(NULL, 16); - SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); - } - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, part_passwd, 16); - DEBUGADD(100,("Password from client was |\n")); - dump_data(100, ntv2_response->data, ntv2_response->length); - DEBUGADD(100,("Variable data from client was |\n")); - dump_data(100, client_key_data.data, client_key_data.length); - DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, sec_blob->data, sec_blob->length); - DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, value_from_encryption, 16); -#endif - data_blob_clear_free(&client_key_data); - return (memcmp(value_from_encryption, client_response, 16) == 0); -} - -/** - * Check a challenge-response password against the value of the NT or - * LM password hash. - * - * @param mem_ctx talloc context - * @param challenge 8-byte challenge. If all zero, forces plaintext comparison - * @param nt_response 'unicode' NT response to the challenge, or unicode password - * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page - * @param username internal Samba username, for log messages - * @param client_username username the client used - * @param client_domain domain name the client used (may be mapped) - * @param nt_pw MD4 unicode password from our passdb or similar - * @param lm_pw LANMAN ASCII password from our passdb or similar - * @param user_sess_key User session key - * @param lm_sess_key LM session key (first 8 bytes of the LM hash) - */ - -static NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, - const DATA_BLOB *challenge, - const DATA_BLOB *lm_response, - const DATA_BLOB *nt_response, - const char *username, - const char *client_username, - const char *client_domain, - const uint8 *lm_pw, const uint8 *nt_pw, - DATA_BLOB *user_sess_key, - DATA_BLOB *lm_sess_key) -{ - static const unsigned char zeros[8]; - if (nt_pw == NULL) { - DEBUG(3,("sam_password_ok: NO NT password stored for user %s.\n", - username)); - } - - /* Check for cleartext netlogon. Used by Exchange 5.5. */ - if (challenge->length == sizeof(zeros) && - (memcmp(challenge->data, zeros, challenge->length) == 0 )) { - - DEBUG(4,("sam_password_ok: checking plaintext passwords for user %s\n", - username)); - if (nt_pw && nt_response->length) { - unsigned char pwhash[16]; - mdfour(pwhash, nt_response->data, nt_response->length); - if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(3,("sam_password_ok: NT (Unicode) plaintext password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - } else if (!lp_lanman_auth()) { - DEBUG(3,("sam_password_ok: (plaintext password check) LANMAN passwords NOT PERMITTED for user %s\n", - username)); - - } else if (lm_pw && lm_response->length) { - uchar dospwd[14]; - uchar p16[16]; - ZERO_STRUCT(dospwd); - - DEBUG(100, ("DOS password: %s\n")); - memcpy(dospwd, lm_response->data, MIN(lm_response->length, sizeof(dospwd))); - /* Only the fisrt 14 chars are considered, password need not be null terminated. */ - E_P16((const unsigned char *)dospwd, p16); - - dump_data_pw("DOS password (first buffer)\n", dospwd, 14); - dump_data_pw("DOS password (wire DES hash)\n", p16, 16); - dump_data_pw("DOS password (passdb DES hash)\n", lm_pw, 16); - if (memcmp(p16, lm_pw, sizeof(p16)) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(3,("sam_password_ok: LANMAN (ASCII) plaintext password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - } else { - DEBUG(3, ("Plaintext authentication for user %s attempted, but neither NT nor LM passwords available\n", username)); - return NT_STATUS_WRONG_PASSWORD; - } - } - - if (nt_response->length != 0 && nt_response->length < 24) { - DEBUG(2,("sam_password_ok: invalid NT password length (%lu) for user %s\n", - (unsigned long)nt_response->length, username)); - } - - if (nt_response->length >= 24 && nt_pw) { - if (nt_response->length > 24) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("sam_password_ok: Checking NTLMv2 password with domain [%s]\n", client_domain)); - if (smb_pwd_check_ntlmv2( nt_response, - nt_pw, challenge, - client_username, - client_domain, - user_sess_key)) { - return NT_STATUS_OK; - } - - DEBUG(4,("sam_password_ok: Checking NTLMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2( nt_response, - nt_pw, challenge, - client_username, - "", - user_sess_key)) { - return NT_STATUS_OK; - } else { - DEBUG(3,("sam_password_ok: NTLMv2 password check failed\n")); - return NT_STATUS_WRONG_PASSWORD; - } - } - - if (lp_ntlm_auth()) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("sam_password_ok: Checking NT MD4 password\n")); - if (smb_pwd_check_ntlmv1(nt_response, - nt_pw, challenge, - user_sess_key)) { - /* The LM session key for this response is not very secure, - so use it only if we otherwise allow LM authentication */ - - if (lp_lanman_auth() && lm_pw) { - uint8 first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - *lm_sess_key = data_blob(first_8_lm_hash, 16); - } - return NT_STATUS_OK; - } else { - DEBUG(3,("sam_password_ok: NT MD4 password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - } else { - DEBUG(2,("sam_password_ok: NTLMv1 passwords NOT PERMITTED for user %s\n", - username)); - /* no return, becouse we might pick up LMv2 in the LM field */ - } - } - - if (lm_response->length == 0) { - DEBUG(3,("sam_password_ok: NEITHER LanMan nor NT password supplied for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (lm_response->length < 24) { - DEBUG(2,("sam_password_ok: invalid LanMan password length (%lu) for user %s\n", - (unsigned long)nt_response->length, username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (!lp_lanman_auth()) { - DEBUG(3,("sam_password_ok: Lanman passwords NOT PERMITTED for user %s\n", - username)); - } else if (!lm_pw) { - DEBUG(3,("sam_password_ok: NO LanMan password set for user %s (and no NT password supplied)\n", - username)); - } else { - DEBUG(4,("sam_password_ok: Checking LM password\n")); - if (smb_pwd_check_ntlmv1(lm_response, - lm_pw, challenge, - NULL)) { - uint8 first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - *user_sess_key = data_blob(first_8_lm_hash, 16); - *lm_sess_key = data_blob(first_8_lm_hash, 16); - return NT_STATUS_OK; - } - } - - if (!nt_pw) { - DEBUG(4,("sam_password_ok: LM password check failed for user, no NT password %s\n",username)); - return NT_STATUS_WRONG_PASSWORD; - } - - /* This is for 'LMv2' authentication. almost NTLMv2 but limited to 24 bytes. - - related to Win9X, legacy NAS pass-though authentication - */ - DEBUG(4,("sam_password_ok: Checking LMv2 password with domain %s\n", client_domain)); - if (smb_pwd_check_ntlmv2( lm_response, - nt_pw, challenge, - client_username, - client_domain, - NULL)) { - return NT_STATUS_OK; - } - - DEBUG(4,("sam_password_ok: Checking LMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2( lm_response, - nt_pw, challenge, - client_username, - "", - NULL)) { - return NT_STATUS_OK; - } - - /* Apparently NT accepts NT responses in the LM field - - I think this is related to Win9X pass-though authentication - */ - DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM field\n")); - if (lp_ntlm_auth()) { - if (smb_pwd_check_ntlmv1(lm_response, - nt_pw, challenge, - NULL)) { - /* The session key for this response is still very odd. - It not very secure, so use it only if we otherwise - allow LM authentication */ - - if (lp_lanman_auth() && lm_pw) { - uint8 first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - *user_sess_key = data_blob(first_8_lm_hash, 16); - *lm_sess_key = data_blob(first_8_lm_hash, 16); - } - return NT_STATUS_OK; - } - DEBUG(3,("sam_password_ok: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username)); - } else { - DEBUG(3,("sam_password_ok: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username)); - } - return NT_STATUS_WRONG_PASSWORD; -} - /**************************************************************************** Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c new file mode 100644 index 0000000000..362b640f91 --- /dev/null +++ b/source3/libsmb/ntlm_check.c @@ -0,0 +1,377 @@ +/* + Unix SMB/CIFS implementation. + Password and authentication handling + Copyright (C) Andrew Tridgell 1992-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Andrew Bartlett 2001-2003 + Copyright (C) Gerald Carter 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +/**************************************************************************** + Core of smb password checking routine. +****************************************************************************/ + +static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, + const uchar *part_passwd, + const DATA_BLOB *sec_blob, + DATA_BLOB *user_sess_key) +{ + /* Finish the encryption of part_passwd. */ + uchar p24[24]; + + if (part_passwd == NULL) { + DEBUG(10,("No password set - DISALLOWING access\n")); + /* No password set - always false ! */ + return False; + } + + if (sec_blob->length != 8) { + DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", + (unsigned long)sec_blob->length)); + return False; + } + + if (nt_response->length != 24) { + DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", + (unsigned long)nt_response->length)); + return False; + } + + SMBOWFencrypt(part_passwd, sec_blob->data, p24); + if (user_sess_key != NULL) { + *user_sess_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key->data); + } + + +#if DEBUG_PASSWORD + DEBUG(100,("Part password (P16) was |\n")); + dump_data(100, part_passwd, 16); + DEBUGADD(100,("Password from client was |\n")); + dump_data(100, nt_response->data, nt_response->length); + DEBUGADD(100,("Given challenge was |\n")); + dump_data(100, sec_blob->data, sec_blob->length); + DEBUGADD(100,("Value from encryption was |\n")); + dump_data(100, p24, 24); +#endif + return (memcmp(p24, nt_response->data, 24) == 0); +} + +/**************************************************************************** + Core of smb password checking routine. (NTLMv2, LMv2) + Note: The same code works with both NTLMv2 and LMv2. +****************************************************************************/ + +static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, + const uchar *part_passwd, + const DATA_BLOB *sec_blob, + const char *user, const char *domain, + DATA_BLOB *user_sess_key) +{ + /* Finish the encryption of part_passwd. */ + uchar kr[16]; + uchar value_from_encryption[16]; + uchar client_response[16]; + DATA_BLOB client_key_data; + + if (part_passwd == NULL) { + DEBUG(10,("No password set - DISALLOWING access\n")); + /* No password set - always False */ + return False; + } + + if (sec_blob->length != 8) { + DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", + (unsigned long)sec_blob->length)); + return False; + } + + if (ntv2_response->length < 24) { + /* We MUST have more than 16 bytes, or the stuff below will go + crazy. No known implementation sends less than the 24 bytes + for LMv2, let alone NTLMv2. */ + DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", + (unsigned long)ntv2_response->length)); + return False; + } + + client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16); + /* + todo: should we be checking this for anything? We can't for LMv2, + but for NTLMv2 it is meant to contain the current time etc. + */ + + memcpy(client_response, ntv2_response->data, sizeof(client_response)); + + if (!ntv2_owf_gen(part_passwd, user, domain, kr)) { + return False; + } + + SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); + if (user_sess_key != NULL) { + *user_sess_key = data_blob(NULL, 16); + SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); + } + +#if DEBUG_PASSWORD + DEBUG(100,("Part password (P16) was |\n")); + dump_data(100, part_passwd, 16); + DEBUGADD(100,("Password from client was |\n")); + dump_data(100, ntv2_response->data, ntv2_response->length); + DEBUGADD(100,("Variable data from client was |\n")); + dump_data(100, client_key_data.data, client_key_data.length); + DEBUGADD(100,("Given challenge was |\n")); + dump_data(100, sec_blob->data, sec_blob->length); + DEBUGADD(100,("Value from encryption was |\n")); + dump_data(100, value_from_encryption, 16); +#endif + data_blob_clear_free(&client_key_data); + return (memcmp(value_from_encryption, client_response, 16) == 0); +} + +/** + * Check a challenge-response password against the value of the NT or + * LM password hash. + * + * @param mem_ctx talloc context + * @param challenge 8-byte challenge. If all zero, forces plaintext comparison + * @param nt_response 'unicode' NT response to the challenge, or unicode password + * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page + * @param username internal Samba username, for log messages + * @param client_username username the client used + * @param client_domain domain name the client used (may be mapped) + * @param nt_pw MD4 unicode password from our passdb or similar + * @param lm_pw LANMAN ASCII password from our passdb or similar + * @param user_sess_key User session key + * @param lm_sess_key LM session key (first 8 bytes of the LM hash) + */ + +NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, + const DATA_BLOB *challenge, + const DATA_BLOB *lm_response, + const DATA_BLOB *nt_response, + const char *username, + const char *client_username, + const char *client_domain, + const uint8 *lm_pw, const uint8 *nt_pw, + DATA_BLOB *user_sess_key, + DATA_BLOB *lm_sess_key) +{ + static const unsigned char zeros[8]; + if (nt_pw == NULL) { + DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", + username)); + } + + /* Check for cleartext netlogon. Used by Exchange 5.5. */ + if (challenge->length == sizeof(zeros) && + (memcmp(challenge->data, zeros, challenge->length) == 0 )) { + + DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n", + username)); + if (nt_pw && nt_response->length) { + unsigned char pwhash[16]; + mdfour(pwhash, nt_response->data, nt_response->length); + if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: NT (Unicode) plaintext password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + } else if (!lp_lanman_auth()) { + DEBUG(3,("ntlm_password_check: (plaintext password check) LANMAN passwords NOT PERMITTED for user %s\n", + username)); + + } else if (lm_pw && lm_response->length) { + uchar dospwd[14]; + uchar p16[16]; + ZERO_STRUCT(dospwd); + + memcpy(dospwd, lm_response->data, MIN(lm_response->length, sizeof(dospwd))); + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ + + /* we *might* need to upper-case the string here */ + E_P16((const unsigned char *)dospwd, p16); + + if (memcmp(p16, lm_pw, sizeof(p16)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: LANMAN (ASCII) plaintext password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + } else { + DEBUG(3, ("Plaintext authentication for user %s attempted, but neither NT nor LM passwords available\n", username)); + return NT_STATUS_WRONG_PASSWORD; + } + } + + if (nt_response->length != 0 && nt_response->length < 24) { + DEBUG(2,("ntlm_password_check: invalid NT password length (%lu) for user %s\n", + (unsigned long)nt_response->length, username)); + } + + if (nt_response->length >= 24 && nt_pw) { + if (nt_response->length > 24) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain)); + if (smb_pwd_check_ntlmv2( nt_response, + nt_pw, challenge, + client_username, + client_domain, + user_sess_key)) { + return NT_STATUS_OK; + } + + DEBUG(4,("ntlm_password_check: Checking NTLMv2 password without a domain\n")); + if (smb_pwd_check_ntlmv2( nt_response, + nt_pw, challenge, + client_username, + "", + user_sess_key)) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n")); + return NT_STATUS_WRONG_PASSWORD; + } + } + + if (lp_ntlm_auth()) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("ntlm_password_check: Checking NT MD4 password\n")); + if (smb_pwd_check_ntlmv1(nt_response, + nt_pw, challenge, + user_sess_key)) { + /* The LM session key for this response is not very secure, + so use it only if we otherwise allow LM authentication */ + + if (lp_lanman_auth() && lm_pw) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: NT MD4 password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + } else { + DEBUG(2,("ntlm_password_check: NTLMv1 passwords NOT PERMITTED for user %s\n", + username)); + /* no return, becouse we might pick up LMv2 in the LM field */ + } + } + + if (lm_response->length == 0) { + DEBUG(3,("ntlm_password_check: NEITHER LanMan nor NT password supplied for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (lm_response->length < 24) { + DEBUG(2,("ntlm_password_check: invalid LanMan password length (%lu) for user %s\n", + (unsigned long)nt_response->length, username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (!lp_lanman_auth()) { + DEBUG(3,("ntlm_password_check: Lanman passwords NOT PERMITTED for user %s\n", + username)); + } else if (!lm_pw) { + DEBUG(3,("ntlm_password_check: NO LanMan password set for user %s (and no NT password supplied)\n", + username)); + } else { + DEBUG(4,("ntlm_password_check: Checking LM password\n")); + if (smb_pwd_check_ntlmv1(lm_response, + lm_pw, challenge, + NULL)) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *user_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + return NT_STATUS_OK; + } + } + + if (!nt_pw) { + DEBUG(4,("ntlm_password_check: LM password check failed for user, no NT password %s\n",username)); + return NT_STATUS_WRONG_PASSWORD; + } + + /* This is for 'LMv2' authentication. almost NTLMv2 but limited to 24 bytes. + - related to Win9X, legacy NAS pass-though authentication + */ + DEBUG(4,("ntlm_password_check: Checking LMv2 password with domain %s\n", client_domain)); + if (smb_pwd_check_ntlmv2( lm_response, + nt_pw, challenge, + client_username, + client_domain, + NULL)) { + return NT_STATUS_OK; + } + + DEBUG(4,("ntlm_password_check: Checking LMv2 password without a domain\n")); + if (smb_pwd_check_ntlmv2( lm_response, + nt_pw, challenge, + client_username, + "", + NULL)) { + return NT_STATUS_OK; + } + + /* Apparently NT accepts NT responses in the LM field + - I think this is related to Win9X pass-though authentication + */ + DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n")); + if (lp_ntlm_auth()) { + if (smb_pwd_check_ntlmv1(lm_response, + nt_pw, challenge, + NULL)) { + /* The session key for this response is still very odd. + It not very secure, so use it only if we otherwise + allow LM authentication */ + + if (lp_lanman_auth() && lm_pw) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *user_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } + return NT_STATUS_OK; + } + DEBUG(3,("ntlm_password_check: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username)); + } else { + DEBUG(3,("ntlm_password_check: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username)); + } + return NT_STATUS_WRONG_PASSWORD; +} + diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index c15a6e8758..788b5de537 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -24,6 +24,8 @@ #include "includes.h" +#undef HAVE_KRB5 + #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -33,6 +35,7 @@ enum stdio_helper_mode { SQUID_2_4_BASIC, SQUID_2_5_BASIC, SQUID_2_5_NTLMSSP, + CLIENT_NTLMSSP_1, GSS_SPNEGO, GSS_SPNEGO_CLIENT, NUM_HELPER_MODES @@ -55,6 +58,9 @@ static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode static void manage_squid_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length); +static void manage_client_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, + char *buf, int length); + static void manage_gss_spnego_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length); @@ -69,6 +75,7 @@ static const struct { { SQUID_2_4_BASIC, "squid-2.4-basic", manage_squid_basic_request}, { SQUID_2_5_BASIC, "squid-2.5-basic", manage_squid_basic_request}, { SQUID_2_5_NTLMSSP, "squid-2.5-ntlmssp", manage_squid_ntlmssp_request}, + { CLIENT_NTLMSSP_1, "client-ntlmssp-1", manage_client_ntlmssp_request}, { GSS_SPNEGO, "gss-spnego", manage_gss_spnego_request}, { GSS_SPNEGO_CLIENT, "gss-spnego-client", manage_gss_spnego_client_request}, { NUM_HELPER_MODES, NULL, NULL} @@ -335,6 +342,112 @@ static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB return nt_status; } +static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key) +{ + static const char zeros[16]; + NTSTATUS nt_status; + uint8 lm_key[8]; + uint8 nt_key[16]; + uint8 lm_pw[16], nt_pw[16]; + + nt_lm_owf_gen (opt_password, nt_pw, lm_pw); + + nt_status = ntlm_password_check(ntlmssp_state->mem_ctx, + &ntlmssp_state->chal, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + ntlmssp_state->user, + ntlmssp_state->user, + ntlmssp_state->domain, + lm_pw, nt_pw, nt_session_key, lm_session_key); + + if (NT_STATUS_IS_OK(nt_status)) { + if (memcmp(lm_key, zeros, 8) != 0) { + *lm_session_key = data_blob(NULL, 16); + memcpy(lm_session_key->data, lm_key, 8); + memset(lm_session_key->data+8, '\0', 8); + } + + if (memcmp(nt_key, zeros, 16) != 0) { + *nt_session_key = data_blob(nt_key, 16); + } + } else { + DEBUG(3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", + ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation, + nt_errstr(nt_status))); + } + return nt_status; +} + +static NTSTATUS ntlm_auth_start_ntlmssp_client(NTLMSSP_STATE **client_ntlmssp_state) +{ + NTSTATUS status; + if ( (opt_username == NULL) || (opt_domain == NULL) ) { + DEBUG(1, ("Need username and domain for NTLMSSP\n")); + return status; + } + + status = ntlmssp_client_start(client_ntlmssp_state); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not start NTLMSSP client: %s\n", + nt_errstr(status))); + ntlmssp_end(client_ntlmssp_state); + return status; + } + + status = ntlmssp_set_username(*client_ntlmssp_state, opt_username); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not set username: %s\n", + nt_errstr(status))); + ntlmssp_end(client_ntlmssp_state); + return status; + } + + status = ntlmssp_set_domain(*client_ntlmssp_state, opt_domain); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not set domain: %s\n", + nt_errstr(status))); + ntlmssp_end(client_ntlmssp_state); + return status; + } + + status = ntlmssp_set_password(*client_ntlmssp_state, opt_password); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not set password: %s\n", + nt_errstr(status))); + ntlmssp_end(client_ntlmssp_state); + return status; + } + return NT_STATUS_OK; +} + +static NTSTATUS ntlm_auth_start_ntlmssp_server(NTLMSSP_STATE **ntlmssp_state) +{ + NTSTATUS status = ntlmssp_server_start(ntlmssp_state); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Could not start NTLMSSP client: %s\n", + nt_errstr(status))); + return status; + } + + /* Have we been given a local password, or should we ask winbind? */ + if (opt_password) { + (*ntlmssp_state)->check_password = local_pw_check; + (*ntlmssp_state)->get_domain = lp_workgroup; + (*ntlmssp_state)->get_global_myname = global_myname; + } else { + (*ntlmssp_state)->check_password = winbind_pw_check; + (*ntlmssp_state)->get_domain = get_winbind_domain; + (*ntlmssp_state)->get_global_myname = get_winbind_netbios_name; + } + return NT_STATUS_OK; +} + static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { @@ -348,6 +461,29 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod return; } + if (strlen(buf) > 3) { + request = base64_decode_data_blob(buf + 3); + } else { + request = data_blob(NULL, 0); + } + + if ((strncmp(buf, "PW ", 3) == 0)) { + /* The calling application wants us to use a local password (rather than winbindd) */ + + opt_password = strndup((const char *)request.data, request.length); + + if (opt_password == NULL) { + DEBUG(1, ("Out of memory\n")); + x_fprintf(x_stdout, "BH\n"); + data_blob_free(&request); + return; + } + + x_fprintf(x_stdout, "OK\n"); + data_blob_free(&request); + return; + } + if (strncmp(buf, "YR", 2) == 0) { if (ntlmssp_state) ntlmssp_end(&ntlmssp_state); @@ -359,17 +495,11 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod return; } - if (strlen(buf) > 3) { - request = base64_decode_data_blob(buf + 3); - } else { - request = data_blob(NULL, 0); - } - if (!ntlmssp_state) { - ntlmssp_server_start(&ntlmssp_state); - ntlmssp_state->check_password = winbind_pw_check; - ntlmssp_state->get_domain = get_winbind_domain; - ntlmssp_state->get_global_myname = get_winbind_netbios_name; + if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) { + x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); + return; + } } DEBUG(10, ("got NTLMSSP packet:\n")); @@ -386,6 +516,8 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); + + ntlmssp_end(&ntlmssp_state); } else if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status)); DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status))); @@ -397,6 +529,102 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod data_blob_free(&request); } +static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, + char *buf, int length) +{ + static NTLMSSP_STATE *ntlmssp_state = NULL; + DATA_BLOB request, reply; + NTSTATUS nt_status; + BOOL first = False; + + if (strlen(buf) < 2) { + DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if (strlen(buf) > 3) { + request = base64_decode_data_blob(buf + 3); + } else { + request = data_blob(NULL, 0); + } + + if (strncmp(buf, "PW ", 3) == 0) { + /* We asked for a password and obviously got it :-) */ + + opt_password = strndup((const char *)request.data, request.length); + + if (opt_password == NULL) { + DEBUG(1, ("Out of memory\n")); + x_fprintf(x_stdout, "BH\n"); + data_blob_free(&request); + return; + } + + x_fprintf(x_stdout, "OK\n"); + data_blob_free(&request); + return; + } + + if (opt_password == NULL) { + + /* Request a password from the calling process. After + sending it, the calling process should retry asking for the negotiate. */ + + DEBUG(10, ("Requesting password\n")); + x_fprintf(x_stdout, "PW\n"); + return; + } + + if (strncmp(buf, "YR", 2) == 0) { + if (ntlmssp_state) + ntlmssp_end(&ntlmssp_state); + } else if (strncmp(buf, "TT", 2) == 0) { + + } else { + DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); + x_fprintf(x_stdout, "BH\n"); + return; + } + + if (!ntlmssp_state) { + if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_client(&ntlmssp_state))) { + x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); + return; + } + first = True; + } + + DEBUG(10, ("got NTLMSSP packet:\n")); + dump_data(10, (const char *)request.data, request.length); + + nt_status = ntlmssp_update(ntlmssp_state, request, &reply); + + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + char *reply_base64 = base64_encode_data_blob(reply); + if (first) { + x_fprintf(x_stdout, "YR %s\n", reply_base64); + } else { + x_fprintf(x_stdout, "KK %s\n", reply_base64); + } + SAFE_FREE(reply_base64); + data_blob_free(&reply); + DEBUG(10, ("NTLMSSP challenge\n")); + } else if (NT_STATUS_IS_OK(nt_status)) { + x_fprintf(x_stdout, "AF\n"); + DEBUG(10, ("NTLMSSP OK!\n")); + if (ntlmssp_state) + ntlmssp_end(&ntlmssp_state); + } else { + x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); + DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); + if (ntlmssp_state) + ntlmssp_end(&ntlmssp_state); + } + + data_blob_free(&request); +} + static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { @@ -561,10 +789,10 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, return; } - ntlmssp_server_start(&ntlmssp_state); - ntlmssp_state->check_password = winbind_pw_check; - ntlmssp_state->get_domain = get_winbind_domain; - ntlmssp_state->get_global_myname = get_winbind_netbios_name; + if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) { + x_fprintf(x_stdout, "BH %s\n", nt_errstr(status)); + return; + } DEBUG(10, ("got NTLMSSP packet:\n")); dump_data(10, (const char *)request.negTokenInit.mechToken.data, @@ -720,11 +948,14 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego) return False; } - if ( (opt_username == NULL) || (opt_domain == NULL) ) { - DEBUG(1, ("Need username and domain for NTLMSSP\n")); - return False; + if (!client_ntlmssp_state) { + if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_client(&client_ntlmssp_state))) { + x_fprintf(x_stdout, "BH %s\n", nt_errstr(status)); + return False; + } } + if (opt_password == NULL) { /* Request a password from the calling process. After @@ -736,42 +967,6 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego) return True; } - status = ntlmssp_client_start(&client_ntlmssp_state); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not start NTLMSSP client: %s\n", - nt_errstr(status))); - ntlmssp_end(&client_ntlmssp_state); - return False; - } - - status = ntlmssp_set_username(client_ntlmssp_state, opt_username); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not set username: %s\n", - nt_errstr(status))); - ntlmssp_end(&client_ntlmssp_state); - return False; - } - - status = ntlmssp_set_domain(client_ntlmssp_state, opt_domain); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not set domain: %s\n", - nt_errstr(status))); - ntlmssp_end(&client_ntlmssp_state); - return False; - } - - status = ntlmssp_set_password(client_ntlmssp_state, opt_password); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not set password: %s\n", - nt_errstr(status))); - ntlmssp_end(&client_ntlmssp_state); - return False; - } - spnego.type = SPNEGO_NEG_TOKEN_INIT; spnego.negTokenInit.mechTypes = my_mechs; spnego.negTokenInit.reqFlags = 0; @@ -1915,7 +2110,12 @@ enum { exit(0); } } - x_fprintf(x_stderr, "unknown helper protocol [%s]\n", helper_protocol); + x_fprintf(x_stderr, "unknown helper protocol [%s]\n\nValid helper protools:\n\n", helper_protocol); + + for (i=0; i Date: Mon, 5 Jan 2004 23:25:56 +0000 Subject: (merge from 3.0) Remove testing hack Make the name of the NTLMSSP client more consistant before we lock it in stone. Andrew Bartlett (This used to be commit 273dcda9ce62eb04c9cce673bb49b41982b26d98) --- source3/utils/ntlm_auth.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 788b5de537..8e688d9614 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -24,8 +24,6 @@ #include "includes.h" -#undef HAVE_KRB5 - #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -35,7 +33,7 @@ enum stdio_helper_mode { SQUID_2_4_BASIC, SQUID_2_5_BASIC, SQUID_2_5_NTLMSSP, - CLIENT_NTLMSSP_1, + NTLMSSP_CLIENT_1, GSS_SPNEGO, GSS_SPNEGO_CLIENT, NUM_HELPER_MODES @@ -75,7 +73,7 @@ static const struct { { SQUID_2_4_BASIC, "squid-2.4-basic", manage_squid_basic_request}, { SQUID_2_5_BASIC, "squid-2.5-basic", manage_squid_basic_request}, { SQUID_2_5_NTLMSSP, "squid-2.5-ntlmssp", manage_squid_ntlmssp_request}, - { CLIENT_NTLMSSP_1, "client-ntlmssp-1", manage_client_ntlmssp_request}, + { NTLMSSP_CLIENT_1, "ntlmssp-client-1", manage_client_ntlmssp_request}, { GSS_SPNEGO, "gss-spnego", manage_gss_spnego_request}, { GSS_SPNEGO_CLIENT, "gss-spnego-client", manage_gss_spnego_client_request}, { NUM_HELPER_MODES, NULL, NULL} -- cgit From 134af28f827ce80856c288e6d850d4fa7a043dd1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:28:50 +0000 Subject: (merge from 3.0) Try to gain a bit more consistancy in the output of usernames from ntlm_auth: Instead of returning a name in DOMAIN\user format, we now return it in the same way that nsswtich does - following the rules of 'winbind use default domain', in the correct case and with the correct seperator. This should help sites who are using Squid or the new SASL code I'm working on, to match back to their unix usernames. -- Get the DOMAIN\username around the right way (I had username\domain...) Push the unix username into utf8 for it's trip across the socket. Andrew Bartlett (This used to be commit 4c2e1189ff84d254f19b604999d011fdb17e538d) --- source3/nsswitch/winbindd_nss.h | 1 + source3/nsswitch/winbindd_pam.c | 26 ++++++++++++++++++++++++++ source3/utils/ntlm_auth.c | 36 +++++++++++++++++++++++++----------- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index 00d49e7d3e..2383db551e 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -152,6 +152,7 @@ typedef struct winbindd_gr { #define WBFLAG_PAM_CONTACT_TRUSTDOM 0x0010 #define WBFLAG_QUERY_ONLY 0x0020 #define WBFLAG_ALLOCATE_RID 0x0040 +#define WBFLAG_PAM_UNIX_NAME 0x0080 /* Winbind request structure */ diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 9962105787..d58c9dcc38 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -365,6 +365,32 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) if (state->request.flags & WBFLAG_PAM_INFO3_NDR) { result = append_info3_as_ndr(mem_ctx, state, &info3); + } else if (state->request.flags & WBFLAG_PAM_UNIX_NAME) { + /* ntlm_auth should return the unix username, per + 'winbind use default domain' settings and the like */ + + fstring username_out; + const char *nt_username, *nt_domain; + if (!(nt_username = unistr2_tdup(mem_ctx, &(info3.uni_user_name)))) { + /* If the server didn't give us one, just use the one we sent them */ + nt_username = user; + } + + if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3.uni_logon_dom)))) { + /* If the server didn't give us one, just use the one we sent them */ + nt_domain = domain; + } + + fill_domain_username(username_out, nt_domain, nt_username); + + DEBUG(5, ("Setting unix username to [%s]\n", username_out)); + + /* this interface is in UTF8 */ + if (push_utf8_allocate((char **)&state->response.extra_data, username_out) == -1) { + result = NT_STATUS_NO_MEMORY; + goto done; + } + state->response.length += strlen(state->response.extra_data)+1; } if (state->request.flags & WBFLAG_PAM_NTKEY) { diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 8e688d9614..cd917f67cd 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -227,7 +227,8 @@ static NTSTATUS contact_winbind_auth_crap(const char *username, uint32 flags, uint8 lm_key[8], uint8 nt_key[16], - char **error_string) + char **error_string, + char **unix_name) { NTSTATUS nt_status; NSS_STATUS result; @@ -302,6 +303,13 @@ static NTSTATUS contact_winbind_auth_crap(const char *username, memcpy(nt_key, response.data.auth.nt_session_key, sizeof(response.data.auth.nt_session_key)); } + + if (flags & WBFLAG_PAM_UNIX_NAME) { + if (pull_utf8_allocate(unix_name, (char *)response.extra_data) == -1) { + return NT_STATUS_NO_MEMORY; + } + } + return nt_status; } @@ -312,15 +320,16 @@ static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB char *error_string; uint8 lm_key[8]; uint8 nt_key[16]; - + char *unix_name; + nt_status = contact_winbind_auth_crap(ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, &ntlmssp_state->chal, &ntlmssp_state->lm_resp, &ntlmssp_state->nt_resp, - WBFLAG_PAM_LMKEY | WBFLAG_PAM_NTKEY, + WBFLAG_PAM_LMKEY | WBFLAG_PAM_NTKEY | WBFLAG_PAM_UNIX_NAME, lm_key, nt_key, - &error_string); + &error_string, &unix_name); if (NT_STATUS_IS_OK(nt_status)) { if (memcmp(lm_key, zeros, 8) != 0) { @@ -332,10 +341,13 @@ static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB if (memcmp(nt_key, zeros, 16) != 0) { *nt_session_key = data_blob(nt_key, 16); } + ntlmssp_state->auth_context = talloc_strdup(ntlmssp_state->mem_ctx, unix_name); + SAFE_FREE(unix_name); } else { DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation, error_string ? error_string : "unknown error (NULL)")); + ntlmssp_state->auth_context = NULL; } return nt_status; } @@ -369,10 +381,12 @@ static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *n if (memcmp(nt_key, zeros, 16) != 0) { *nt_session_key = data_blob(nt_key, 16); } + ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state->mem_ctx, "%s%c%s", ntlmssp_state->domain, *lp_winbind_separator(), ntlmssp_state->user); } else { DEBUG(3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation, nt_errstr(nt_status))); + ntlmssp_state->auth_context = NULL; } return nt_status; } @@ -520,7 +534,7 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status)); DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status))); } else { - x_fprintf(x_stdout, "AF %s\\%s\n", ntlmssp_state->domain, ntlmssp_state->user); + x_fprintf(x_stdout, "AF %s\n", (char *)ntlmssp_state->auth_context); DEBUG(10, ("NTLMSSP OK!\n")); } @@ -1368,7 +1382,7 @@ static BOOL check_auth_crap(void) flags, (unsigned char *)lm_key, (unsigned char *)nt_key, - &error_string); + &error_string, NULL); if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "%s (0x%x)\n", @@ -1476,7 +1490,7 @@ static BOOL test_lm_ntlm_broken(enum ntlm_break break_which) flags, lm_key, nt_key, - &error_string); + &error_string, NULL); data_blob_free(&lm_response); @@ -1575,7 +1589,7 @@ static BOOL test_ntlm_in_lm(void) flags, lm_key, nt_key, - &error_string); + &error_string, NULL); data_blob_free(&nt_response); @@ -1646,7 +1660,7 @@ static BOOL test_ntlm_in_both(void) flags, (unsigned char *)lm_key, (unsigned char *)nt_key, - &error_string); + &error_string, NULL); data_blob_free(&nt_response); @@ -1737,7 +1751,7 @@ static BOOL test_lmv2_ntlmv2_broken(enum ntlm_break break_which) flags, NULL, nt_key, - &error_string); + &error_string, NULL); data_blob_free(&lmv2_response); data_blob_free(&ntlmv2_response); @@ -1881,7 +1895,7 @@ static BOOL test_plaintext(enum ntlm_break break_which) flags, lm_key, nt_key, - &error_string); + &error_string, NULL); SAFE_FREE(nt_response.data); SAFE_FREE(lm_response.data); -- cgit From b46ec1aac99454fff4419f5db1f460543597ebe4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:37:07 +0000 Subject: (merge from 3.0) auth/auth_util.c: - Fill in the 'backup' idea of a domain, if the DC didn't supply one. This doesn't seem to occour in reality, hence why we missed the typo. lib/charcnv.c: lib/smbldap.c: libads/ldap.c: libsmb/libsmbclient.c: printing/nt_printing.c: - all the callers to pull_utf8_allocate() pass a char ** as the first parammeter, so don't make them all cast it to a void ** nsswitch/winbind_util.c: - Allow for a more 'correct' view of when usernames should be qualified in winbindd. If we are a PDC, or have 'winbind trusted domains only', then for the authentication returns stip the domain portion. - Fix valgrind warning about use of free()ed name when looking up our local domain. lp_workgroup() is maniplated inside a procedure that uses it's former value. Instead, use the fact that our local domain is always the first in the list. -- Jerry rightly complained that we can't assume that the first domain is our primary domain - new domains are added to the front of the list. :-( Use a much more reliable 'flag test' instead. (note: changes winbind structures, make clean). -- Forgot to commit this for the 'get our primary domain' change. Andrew Bartlett (This used to be commit acacd27ba25f7ebfec40bfa66d34ece543569e23) --- source3/auth/auth_util.c | 2 +- source3/lib/charcnv.c | 4 +- source3/lib/smbldap.c | 2 +- source3/libads/ldap.c | 2 +- source3/libsmb/libsmbclient.c | 2 +- source3/nsswitch/winbindd.h | 1 + source3/nsswitch/winbindd_util.c | 80 ++++++++++++++++++++++++++++++++-------- source3/printing/nt_printing.c | 4 +- 8 files changed, 74 insertions(+), 23 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index c474049617..0f945b33cb 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -1078,7 +1078,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) { /* If the server didn't give us one, just use the one we sent them */ - domain = domain; + nt_domain = domain; } /* try to fill the SAM account.. If getpwnam() fails, then try the diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index d6eb336d31..7903dfd3f6 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -1011,11 +1011,11 @@ size_t pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src) * @returns The number of bytes occupied by the string in the destination **/ -size_t pull_utf8_allocate(void **dest, const char *src) +size_t pull_utf8_allocate(char **dest, const char *src) { size_t src_len = strlen(src)+1; *dest = NULL; - return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, dest); + return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, (void **)dest); } /** diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index e05d127d91..2eeec156bd 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -1196,7 +1196,7 @@ char *smbldap_get_dn(LDAP *ld, LDAPMessage *entry) DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n")); return NULL; } - if (pull_utf8_allocate((void **) &unix_dn, utf8_dn) == (size_t)-1) { + if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) { DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 [%s]\n", utf8_dn)); return NULL; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6e40089b70..9828acccba 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -714,7 +714,7 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) return NULL; } - if (pull_utf8_allocate((void **) &unix_dn, utf8_dn) == (size_t)-1) { + if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) { DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n", utf8_dn )); return NULL; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 21273ec431..37e794478d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -144,7 +144,7 @@ decode_urlpart(char *segment, size_t sizeof_segment) free(new_usegment); /* realloc it with unix charset */ - pull_utf8_allocate((void**)&new_usegment, new_segment); + pull_utf8_allocate(&new_usegment, new_segment); /* this assumes (very safely) that removing %aa sequences only shortens the string */ diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 677afa1849..f1a58ab451 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -96,6 +96,7 @@ struct winbindd_domain { fstring alt_name; /* alt Domain name (if any) */ DOM_SID sid; /* SID for this domain */ BOOL native_mode; /* is this a win2k domain in native mode ? */ + BOOL primary; /* is this our primary domain ? */ /* Lookup methods for this domain (LDAP or RPC) */ struct winbindd_methods *methods; diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 6d1675752f..318da4a63a 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -52,8 +52,9 @@ struct winbindd_domain *domain_list(void) { /* Initialise list */ - if (!_domain_list) - init_domain_list(); + if (!_domain_list) + if (!init_domain_list()) + return NULL; return _domain_list; } @@ -166,9 +167,7 @@ void rescan_trusted_domains( void ) if ( (now > last_scan) && ((now-last_scan) < WINBINDD_RESCAN_FREQ) ) return; - /* get the handle for our domain */ - - if ( (mydomain = find_domain_from_name(lp_workgroup())) == NULL ) { + if ( (mydomain = find_our_domain()) == NULL ) { DEBUG(0,("rescan_trusted_domains: Can't find my own domain!\n")); return; } @@ -266,10 +265,12 @@ BOOL init_domain_list(void) /* Free existing list */ free_domain_list(); - /* Add ourselves as the first entry */ + /* Add ourselves as the first entry. It *must* be the first entry */ domain = add_trusted_domain( lp_workgroup(), lp_realm(), &cache_methods, NULL); + domain->primary = True; + /* get any alternate name for the primary domain */ cache_methods.alternate_name(domain); @@ -291,8 +292,17 @@ BOOL init_domain_list(void) return True; } -/* Given a domain name, return the struct winbindd domain info for it - if it is actually working. */ +/** + * Given a domain name, return the struct winbindd domain info for it + * + * @note Do *not* pass lp_workgroup() to this function. domain_list + * may modify it's value, and free that pointer. Instead, our local + * domain may be found by looking at the first entry in domain_list() + * directly. + * + * + * @return The domain structure for the named domain, if it is working. + */ struct winbindd_domain *find_domain_from_name(const char *domain_name) { @@ -302,8 +312,9 @@ struct winbindd_domain *find_domain_from_name(const char *domain_name) for (domain = domain_list(); domain != NULL; domain = domain->next) { if (strequal(domain_name, domain->name) || - (domain->alt_name[0] && strequal(domain_name, domain->alt_name))) + (domain->alt_name[0] && strequal(domain_name, domain->alt_name))) { return domain; + } } /* Not found */ @@ -329,6 +340,24 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid) return NULL; } +/* Given a domain sid, return the struct winbindd domain info for it */ + +struct winbindd_domain *find_our_domain() +{ + struct winbindd_domain *domain; + + /* Search through list */ + + for (domain = domain_list(); domain != NULL; domain = domain->next) { + if (domain->primary) + return domain; + } + + /* Not found */ + + return NULL; +} + /* Lookup a sid in a domain from a name */ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, @@ -471,6 +500,20 @@ BOOL check_domain_env(char *domain_env, char *domain) return False; } +/* Is this a domain which we may assume no DOMAIN\ prefix? */ + +static BOOL assume_domain(const char *domain) { + if ((lp_winbind_use_default_domain() + || lp_winbind_trusted_domains_only()) && + strequal(lp_workgroup(), domain)) + return True; + + if (strequal(get_global_sam_name(), domain)) + return True; + + return False; +} + /* Parse a string of the form DOMAIN/user into a domain and a user */ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) @@ -480,10 +523,13 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) if ( !p ) { fstrcpy(user, domuser); - if ( lp_winbind_use_default_domain() ) + if ( assume_domain(lp_workgroup())) { fstrcpy(domain, lp_workgroup()); - else - fstrcpy( domain, "" ); + } else if (assume_domain(get_global_sam_name())) { + fstrcpy( domain, get_global_sam_name() ); + } else { + fstrcpy( domain, ""); + } } else { fstrcpy(user, p+1); @@ -501,13 +547,17 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) 'winbind separator' options. This means: - omit DOMAIN when 'winbind use default domain = true' and DOMAIN is - lp_workgroup + lp_workgroup() + + If we are a PDC or BDC, and this is for our domain, do likewise. + + Also, if omit DOMAIN if 'winbind trusted domains only = true', as the + username is then unqualified in unix */ void fill_domain_username(fstring name, const char *domain, const char *user) { - if(lp_winbind_use_default_domain() && - !strcmp(lp_workgroup(), domain)) { + if (assume_domain(domain)) { strlcpy(name, user, sizeof(fstring)); } else { slprintf(name, sizeof(fstring) - 1, "%s%s%s", diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 7ba777f131..34274d1831 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2662,13 +2662,13 @@ static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer) return WERR_SERVER_UNAVAILABLE; } /* Now convert to CH_UNIX. */ - if (pull_utf8_allocate((void **) &srv_dn, srv_dn_utf8) == (size_t)-1) { + if (pull_utf8_allocate(&srv_dn, srv_dn_utf8) == (size_t)-1) { ldap_memfree(srv_dn_utf8); ldap_memfree(srv_cn_utf8); ads_destroy(&ads); return WERR_SERVER_UNAVAILABLE; } - if (pull_utf8_allocate((void **) &srv_cn_0, srv_cn_utf8[0]) == (size_t)-1) { + if (pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0]) == (size_t)-1) { ldap_memfree(srv_dn_utf8); ldap_memfree(srv_cn_utf8); ads_destroy(&ads); -- cgit From 0c78e6fc3e8df9ad9480d3b1b6b2d5a3eb19bf45 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:38:49 +0000 Subject: (merge from 3.0) Changes to our PAM code to cope with the fact that we can't handle some domains (in particular, the domain of the current machine, if it is not a PDC) By changing the error codes, we now return values that PAM can correctly use for better stacking of PAM modules - in particular of the password change module. This allows pam_winbind to co-exist with other pam modules for password changes. Andrew Bartlett (This used to be commit 06b4eb4b9f867998c8faf9a91830ba3181cdf605) --- source3/nsswitch/winbindd_pam.c | 48 +++++++++++++++++++++++++++++----------- source3/nsswitch/winbindd_util.c | 4 +--- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index d58c9dcc38..3ca91b1c07 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -95,11 +95,6 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) /* Parse domain and username */ parse_domain_user(state->request.data.auth.user, name_domain, name_user); - if ( !*name_domain ) { - DEBUG(5,("no domain separator (%s) in username (%s) - failing auth\n", lp_winbind_separator(), state->request.data.auth.user)); - result = NT_STATUS_INVALID_PARAMETER; - goto done; - } /* do password magic */ @@ -118,11 +113,23 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) /* what domain should we contact? */ - if ( IS_DC ) + if ( IS_DC ) { + if (!find_domain_from_name(name_domain)) { + DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", + state->request.data.auth.user, name_domain, name_user, name_domain)); + result = NT_STATUS_NO_SUCH_USER; + goto done; + } contact_domain = name_domain; - else - contact_domain = lp_workgroup(); + } else { + if (is_myname(name_domain)) { + DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain)); + result = NT_STATUS_NO_SUCH_USER; + goto done; + } + contact_domain = lp_workgroup(); + } /* check authentication loop */ do { @@ -304,11 +311,23 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) /* what domain should we contact? */ - if ( IS_DC ) + if ( IS_DC ) { + if (!find_domain_from_name(domain)) { + DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", + state->request.data.auth.user, domain, user, domain)); + result = NT_STATUS_NO_SUCH_USER; + goto done; + } contact_domain = domain; - else + } else { + if (is_myname(domain)) { + DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", domain)); + result = NT_STATUS_NO_SUCH_USER; + goto done; + } contact_domain = lp_workgroup(); - + } + do { ZERO_STRUCT(info3); ZERO_STRUCT(ret_creds); @@ -446,8 +465,11 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) return WINBINDD_ERROR; parse_domain_user(state->request.data.chauthtok.user, domain, user); - if ( !*domain ) { - result = NT_STATUS_INVALID_PARAMETER; + + if (!find_domain_from_name(domain)) { + DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", + state->request.data.chauthtok.user, domain, user, domain)); + result = NT_STATUS_NO_SUCH_USER; goto done; } diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 318da4a63a..0f14a7e413 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -525,10 +525,8 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) if ( assume_domain(lp_workgroup())) { fstrcpy(domain, lp_workgroup()); - } else if (assume_domain(get_global_sam_name())) { - fstrcpy( domain, get_global_sam_name() ); } else { - fstrcpy( domain, ""); + fstrcpy( domain, get_global_sam_name() ); } } else { -- cgit From 17b22be3c9b286bb20481db1ab7c5c3a09138fe9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:41:50 +0000 Subject: (merge from 3.0) JHT came up with a nasty (broken) torture case in preparing examples for his book. This prompted me to look at the code that reads the unix group list. This code did a lot of name -> uid -> name -> sid translations, which caused problems. Instead, we now do just name -> sid I also cleaned up some interfaces, and client tools. Andrew Bartlett (This used to be commit cc535a6c70d8dcf677322e31b24dec58b23d80f0) --- source3/groupdb/mapping.c | 91 ++++++++++++++++-------- source3/passdb/passdb.c | 2 +- source3/rpc_server/srv_samr_nt.c | 149 +++++++++++++-------------------------- source3/utils/net_rpc.c | 5 +- source3/utils/net_rpc_samsync.c | 4 +- 5 files changed, 118 insertions(+), 133 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 08ac6a25a5..97abbd46e3 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -551,7 +551,7 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) /* get a local (alias) group from it's SID */ -BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) +BOOL get_local_group_from_sid(DOM_SID *sid, GROUP_MAP *map) { BOOL ret; @@ -562,7 +562,7 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) /* The group is in the mapping table */ become_root(); - ret = pdb_getgrsid(map, sid); + ret = pdb_getgrsid(map, *sid); unbecome_root(); if ( !ret ) @@ -585,7 +585,7 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) uint32 alias_rid; struct group *grp; - sid_peek_rid(&sid, &alias_rid); + sid_peek_rid(sid, &alias_rid); map->gid=pdb_group_rid_to_gid(alias_rid); grp = getgrgid(map->gid); @@ -599,7 +599,7 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) fstrcpy(map->nt_name, grp->gr_name); fstrcpy(map->comment, "Local Unix Group"); - sid_copy(&map->sid, &sid); + sid_copy(&map->sid, sid); } #endif @@ -608,7 +608,7 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) /* get a builtin group from it's SID */ -BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map) +BOOL get_builtin_group_from_sid(DOM_SID *sid, GROUP_MAP *map) { struct group *grp; BOOL ret; @@ -620,7 +620,7 @@ BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map) } become_root(); - ret = pdb_getgrsid(map, sid); + ret = pdb_getgrsid(map, *sid); unbecome_root(); if ( !ret ) @@ -690,7 +690,7 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) Get the member users of a group and all the users who have that group as primary. - give back an array of uid + give back an array of SIDS return the grand number of users @@ -698,21 +698,21 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) ****************************************************************************/ -BOOL get_uid_list_of_group(gid_t gid, uid_t **uid, int *num_uids) +BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids) { struct group *grp; struct passwd *pwd; int i=0; char *gr; - uid_t *u; + DOM_SID *s; if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping")); return(False); } - *num_uids = 0; - *uid=NULL; + *num_sids = 0; + *sids=NULL; if ( (grp=getgrgid(gid)) == NULL) return False; @@ -721,39 +721,74 @@ BOOL get_uid_list_of_group(gid_t gid, uid_t **uid, int *num_uids) DEBUG(10, ("getting members\n")); while (gr && (*gr != (char)'\0')) { - u = Realloc((*uid), sizeof(uid_t)*(*num_uids+1)); - if (!u) { - DEBUG(0,("get_uid_list_of_group: unable to enlarge uid list!\n")); + SAM_ACCOUNT *group_member_acct = NULL; + BOOL found_user; + s = Realloc((*sids), sizeof(**sids)*(*num_sids+1)); + if (!s) { + DEBUG(0,("get_uid_list_of_group: unable to enlarge SID list!\n")); return False; } - else (*uid) = u; + else (*sids) = s; + + if (!NT_STATUS_IS_OK(pdb_init_sam(&group_member_acct))) { + continue; + } - if( (pwd=getpwnam_alloc(gr)) !=NULL) { - (*uid)[*num_uids]=pwd->pw_uid; - (*num_uids)++; - passwd_free(&pwd); + become_root(); + found_user = pdb_getsampwnam(group_member_acct, gr); + unbecome_root(); + + if (found_user) { + sid_copy(&(*sids)[*num_sids], pdb_get_user_sid(group_member_acct)); + (*num_sids)++; } + + pdb_free_sam(&group_member_acct); + gr = grp->gr_mem[++i]; } - DEBUG(10, ("got [%d] members\n", *num_uids)); + DEBUG(10, ("got [%d] members\n", *num_sids)); + + winbind_off(); setpwent(); while ((pwd=getpwent()) != NULL) { if (pwd->pw_gid==gid) { - u = Realloc((*uid), sizeof(uid_t)*(*num_uids+1)); - if (!u) { - DEBUG(0,("get_uid_list_of_group: unable to enlarge uid list!\n")); + SAM_ACCOUNT *group_member_acct = NULL; + BOOL found_user; + s = Realloc((*sids), sizeof(**sids)*(*num_sids+1)); + if (!s) { + DEBUG(0,("get_sid_list_of_group: unable to enlarge SID list!\n")); + winbind_on(); return False; } - else (*uid) = u; - (*uid)[*num_uids]=pwd->pw_uid; - - (*num_uids)++; + else (*sids) = s; + + if (!NT_STATUS_IS_OK(pdb_init_sam(&group_member_acct))) { + continue; + } + + become_root(); + found_user = pdb_getsampwnam(group_member_acct, pwd->pw_name); + unbecome_root(); + + if (found_user) { + sid_copy(&(*sids)[*num_sids], pdb_get_user_sid(group_member_acct)); + (*num_sids)++; + } else { + DEBUG(4,("get_sid_list_of_group: User %s [uid == %lu] has no samba account\n", + pwd->pw_name, (unsigned long)pwd->pw_uid)); + if (algorithmic_uid_to_sid(&(*sids)[*num_sids], pwd->pw_uid)) + (*num_sids)++; + } + + pdb_free_sam(&group_member_acct); } } endpwent(); - DEBUG(10, ("got primary groups, members: [%d]\n", *num_uids)); + DEBUG(10, ("got primary groups, members: [%d]\n", *num_sids)); + winbind_on(); return True; } diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index f4acb2fbf6..7f1861f0bf 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1074,7 +1074,7 @@ BOOL local_password_change(const char *user_name, int local_flags, Convert a uid to SID - algorithmic. ****************************************************************************/ -static DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid) +DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid) { if ( !lp_enable_rid_algorithm() ) return NULL; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 4d4dfed47c..be5f197198 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3176,18 +3176,15 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ int i; GROUP_MAP map; - int num_uids = 0; + int num_sids = 0; DOM_SID2 *sid; - uid_t *uid=NULL; + DOM_SID *sids=NULL; DOM_SID alias_sid; DOM_SID als_sid; uint32 alias_rid; fstring alias_sid_str; - DOM_SID temp_sid; - SAM_ACCOUNT *sam_user = NULL; - BOOL check; uint32 acc_granted; /* find the policy handle. open a policy on it. */ @@ -3207,65 +3204,40 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ if (sid_equal(&alias_sid, &global_sid_Builtin)) { DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n")); - if(!get_builtin_group_from_sid(als_sid, &map)) + if(!get_builtin_group_from_sid(&als_sid, &map)) return NT_STATUS_NO_SUCH_ALIAS; } else { if (sid_equal(&alias_sid, get_global_sam_sid())) { DEBUG(10, ("lookup on Server SID\n")); - if(!get_local_group_from_sid(als_sid, &map)) + if(!get_local_group_from_sid(&als_sid, &map)) { + fstring alias_sid_string; + DEBUG(10, ("Alias %s not found\n", sid_to_string(alias_sid_string, &als_sid))); return NT_STATUS_NO_SUCH_ALIAS; + } } } - if(!get_uid_list_of_group(map.gid, &uid, &num_uids)) + if (!get_sid_list_of_group(map.gid, &sids, &num_sids)) { + fstring alias_sid_string; + DEBUG(10, ("Alias %s found, but member list unavailable\n", sid_to_string(alias_sid_string, &als_sid))); return NT_STATUS_NO_SUCH_ALIAS; + } DEBUG(10, ("sid is %s\n", alias_sid_str)); - sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids); - if (num_uids!=0 && sid == NULL) + sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_sids); + if (num_sids!=0 && sid == NULL) { + SAFE_FREE(sids); return NT_STATUS_NO_MEMORY; + } - for (i = 0; i < num_uids; i++) { - struct passwd *pass; - uint32 rid; - - sid_copy(&temp_sid, get_global_sam_sid()); - - pass = getpwuid_alloc(uid[i]); - if (!pass) continue; - - if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) { - passwd_free(&pass); - continue; - } - - become_root(); - check = pdb_getsampwnam(sam_user, pass->pw_name); - unbecome_root(); - - if (check != True) { - pdb_free_sam(&sam_user); - passwd_free(&pass); - continue; - } - - rid = pdb_get_user_rid(sam_user); - if (rid == 0) { - pdb_free_sam(&sam_user); - passwd_free(&pass); - continue; - } - - pdb_free_sam(&sam_user); - passwd_free(&pass); - - sid_append_rid(&temp_sid, rid); - - init_dom_sid2(&sid[i], &temp_sid); + for (i = 0; i < num_sids; i++) { + init_dom_sid2(&sid[i], &sids[i]); } DEBUG(10, ("sid is %s\n", alias_sid_str)); - init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK); + init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK); + + SAFE_FREE(sids); return NT_STATUS_OK; } @@ -3276,20 +3248,19 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u) { - int num_uids = 0; + int num_sids = 0; + int final_num_sids = 0; int i; DOM_SID group_sid; uint32 group_rid; fstring group_sid_str; - uid_t *uid=NULL; + DOM_SID *sids=NULL; GROUP_MAP map; uint32 *rid=NULL; uint32 *attr=NULL; - SAM_ACCOUNT *sam_user = NULL; - BOOL check; uint32 acc_granted; /* find the policy handle. open a policy on it. */ @@ -3316,52 +3287,32 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_ if(!get_domain_group_from_sid(group_sid, &map)) return NT_STATUS_NO_SUCH_GROUP; - if(!get_uid_list_of_group(map.gid, &uid, &num_uids)) + if(!get_sid_list_of_group(map.gid, &sids, &num_sids)) return NT_STATUS_NO_SUCH_GROUP; - rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids); - attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids); + rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_sids); + attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_sids); - if (num_uids!=0 && (rid==NULL || attr==NULL)) + if (num_sids!=0 && (rid==NULL || attr==NULL)) return NT_STATUS_NO_MEMORY; - for (i=0; ipw_name); - unbecome_root(); - - if (check != True) { - pdb_free_sam(&sam_user); - passwd_free(&pass); - continue; - } - - urid = pdb_get_user_rid(sam_user); - if (urid == 0) { - pdb_free_sam(&sam_user); - passwd_free(&pass); - continue; + + if (sid_peek_check_rid(get_global_sam_sid(), &sids[i], &urid)) { + rid[final_num_sids] = urid; + attr[final_num_sids] = SID_NAME_USER; + final_num_sids++; + } else { + fstring user_sid_str, domain_sid_str; + DEBUG(1, ("_samr_query_groupmem: SID %s in group %s is not in our domain %s\n", + sid_to_string(user_sid_str, &sids[i]), + sid_to_string(group_sid_str, &group_sid), + sid_to_string(domain_sid_str, get_global_sam_sid()))); } - - pdb_free_sam(&sam_user); - passwd_free(&pass); - - rid[i] = urid; - attr[i] = SID_NAME_USER; } - init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK); + init_samr_r_query_groupmem(r_u, final_num_sids, rid, attr, NT_STATUS_OK); return NT_STATUS_OK; } @@ -3397,13 +3348,13 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD if (sid_compare(&alias_sid, get_global_sam_sid())>0) { DEBUG(10, ("adding member on Server SID\n")); - if(!get_local_group_from_sid(alias_sid, &map)) + if(!get_local_group_from_sid(&alias_sid, &map)) return NT_STATUS_NO_SUCH_ALIAS; } else { if (sid_compare(&alias_sid, &global_sid_Builtin)>0) { DEBUG(10, ("adding member on BUILTIN SID\n")); - if( !get_local_group_from_sid(alias_sid, &map)) + if( !get_local_group_from_sid(&alias_sid, &map)) return NT_STATUS_NO_SUCH_ALIAS; } else @@ -3494,7 +3445,7 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE return NT_STATUS_NO_SUCH_ALIAS; } - if( !get_local_group_from_sid(alias_sid, &map)) + if( !get_local_group_from_sid(&alias_sid, &map)) return NT_STATUS_NO_SUCH_ALIAS; if ((grp=getgrgid(map.gid)) == NULL) @@ -3882,7 +3833,7 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S DEBUG(10, ("lookup on Local SID\n")); - if(!get_local_group_from_sid(alias_sid, &map)) + if(!get_local_group_from_sid(&alias_sid, &map)) return NT_STATUS_NO_SUCH_ALIAS; gid=map.gid; @@ -4042,8 +3993,8 @@ NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAM { DOM_SID group_sid; GROUP_MAP map; - uid_t *uid=NULL; - int num_uids=0; + DOM_SID *sids=NULL; + int num_sids=0; GROUP_INFO_CTR *ctr; uint32 acc_granted; BOOL ret; @@ -4068,10 +4019,10 @@ NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAM switch (q_u->switch_level) { case 1: ctr->switch_value1 = 1; - if(!get_uid_list_of_group(map.gid, &uid, &num_uids)) + if(!get_sid_list_of_group(map.gid, &sids, &num_sids)) return NT_STATUS_NO_SUCH_GROUP; - init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids); - SAFE_FREE(uid); + init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_sids); + SAFE_FREE(sids); break; case 3: ctr->switch_value1 = 3; @@ -4153,7 +4104,7 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_ return r_u->status; } - if (!get_local_group_from_sid(group_sid, &map)) + if (!get_local_group_from_sid(&group_sid, &map)) return NT_STATUS_NO_SUCH_GROUP; ctr=&q_u->ctr; diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 04a0330774..b28365274c 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1158,7 +1158,7 @@ rpc_group_members_internals(const DOM_SID *domain_sid, struct cli_state *cli, if (!NT_STATUS_IS_OK(result)) goto done; - do { + while (num_members > 0) { int this_time = 512; if (num_members < this_time) @@ -1177,8 +1177,7 @@ rpc_group_members_internals(const DOM_SID *domain_sid, struct cli_state *cli, num_members -= this_time; group_rids += 512; - - } while (num_members > 0); + } done: return result; diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index d1c8300a49..e97a362acc 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -783,13 +783,13 @@ fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid) if (sid_equal(&dom_sid, &global_sid_Builtin)) { sid_type = SID_NAME_WKN_GRP; - if (!get_builtin_group_from_sid(group_sid, &map, False)) { + if (!get_builtin_group_from_sid(&group_sid, &map, False)) { DEBUG(0, ("Could not find builtin group %s\n", sid_string_static(&group_sid))); return NT_STATUS_NO_SUCH_GROUP; } } else { sid_type = SID_NAME_ALIAS; - if (!get_local_group_from_sid(group_sid, &map, False)) { + if (!get_local_group_from_sid(&group_sid, &map, False)) { DEBUG(0, ("Could not find local group %s\n", sid_string_static(&group_sid))); return NT_STATUS_NO_SUCH_GROUP; } -- cgit From 3eb6b2a6c3f36cbc03c458d50586a6cf5e518002 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:43:07 +0000 Subject: (merge from 3.0) Having no members of a group is a perfectly valid (if unusual) situation. Andrew Bartlett (This used to be commit bc77b586be6992a662422304dbefbd4b833818fb) --- source3/nsswitch/winbindd_rpc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index b13d419110..916ae78d21 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -631,6 +631,13 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, if (!NT_STATUS_IS_OK(result)) goto done; + if (!*num_names) { + names = NULL; + name_types = NULL; + sid_mem = NULL; + goto done; + } + /* Step #2: Convert list of rids into list of usernames. Do this in bunches of ~1000 to avoid crashing NT4. It looks like there is a buffer overflow or something like that lurking around -- cgit From ed8e23c3875c87dd867dd21e06242fad57b881d0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:45:14 +0000 Subject: (merge from 3.0) Match Win2k, and return NT_STATUS_INVALID_PARAMETER if this parameter is not an account type Andrew Bartlett (This used to be commit 43ee2e0b6a6f95ce2864befeb08b5de2ace41c7c) --- source3/rpc_server/srv_samr_nt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index be5f197198..bd26ce6849 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2135,9 +2135,9 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA return nt_status; } - if (!acb_info) { + if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) { /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if - this parameter is zero (ie, no user type specified) */ + this parameter is not an account type */ return NT_STATUS_INVALID_PARAMETER; } -- cgit From 1c9fa70c7cf16ad407f9da68b5159a0d4dc298bc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:48:04 +0000 Subject: (merge from 3.0) Even if the 'device type' is always an ascii string, use push_string to get it out onto the wire. Avoids valgrind warnings because the fstrcpy() causes part of the wire buffer to be 'marked'. Andrew Bartlett (This used to be commit 326becbde23c8039e1f0f00930bcab094bf91ed2) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b140c772a2..28de7fc9f3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -903,7 +903,7 @@ BOOL cli_send_tconX(struct cli_state *cli, memcpy(p,pword,passlen); p += passlen; p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER); - fstrcpy(p, dev); p += strlen(dev)+1; + p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII); cli_setup_bcc(cli, p); -- cgit From 716d933a858265a664bc5dc862d24bda9473e816 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:51:34 +0000 Subject: (merge from 3.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix for bug 707, getent group for huge ads groups (>1500 members) This introduces range retrieval of ADS attributes. VL rewrote most of Güther's patch, partly to remove code duplication and partly to get the retrieval of members in one rush, not interrupted by the lookups for the DN. I rewrote that patch, to ensure that we can keep an eye on the USN (sequence number) of the entry - this allows us to ensure the read was atomic. In particular, the range retrieval is now generic, for strings. It could easily be made generic for any attribute type, if need be. Andrew Bartlett (This used to be commit 08e851c7417d52a86e31982fcfce695c8a6360b7) --- source3/libads/ldap.c | 138 +++++++++++++++++++++++++++++++++++++--- source3/nsswitch/winbindd_ads.c | 94 ++++++++++++++++++++------- 2 files changed, 202 insertions(+), 30 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9828acccba..8aaca01bbf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1573,27 +1573,26 @@ char *ads_pull_string(ADS_STRUCT *ads, * @return Result strings in talloc context **/ char **ads_pull_strings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field) + TALLOC_CTX *mem_ctx, void *msg, const char *field, + size_t *num_values) { char **values; char **ret = NULL; - int i, n; + int i; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; - for (i=0;values[i];i++) - /* noop */ ; - n = i; + *num_values = ldap_count_values(values); - ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); if (!ret) { ldap_value_free(values); return NULL; } - for (i=0;iname, sid_string_static(group_sid))); @@ -708,34 +712,80 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, sidstr = sid_binstring(group_sid); /* search for all members of the group */ - asprintf(&ldap_exp, "(objectSid=%s)",sidstr); - rc = ads_search_retry(ads, &res, ldap_exp, attrs); - free(ldap_exp); - free(sidstr); - - if (!ADS_ERR_OK(rc) || !res) { - DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc))); + if (!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)",sidstr))) { + SAFE_FREE(sidstr); + DEBUG(1, ("ads: lookup_groupmem: tallloc_asprintf for ldap_exp failed!\n")); + status = NT_STATUS_NO_MEMORY; goto done; } + SAFE_FREE(sidstr); - count = ads_count_replies(ads, res); - if (count == 0) { - status = NT_STATUS_OK; - goto done; - } + members = NULL; + num_members = 0; - members = ads_pull_strings(ads, mem_ctx, res, "member"); - if (!members) { - /* no members? ok ... */ - status = NT_STATUS_OK; - goto done; - } + attrs = talloc(mem_ctx, 3 * sizeof(*attrs)); + attrs[1] = talloc_strdup(mem_ctx, "usnChanged"); + attrs[2] = NULL; + + do { + if (num_members == 0) + attrs[0] = talloc_strdup(mem_ctx, "member"); + DEBUG(10, ("Searching for attrs[0] = %s, attrs[1] = %s\n", attrs[0], attrs[1])); + + rc = ads_search_retry(ads, &res, ldap_exp, attrs); + + if (!ADS_ERR_OK(rc) || !res) { + DEBUG(1,("ads: lookup_groupmem ads_search: %s\n", + ads_errstr(rc))); + status = ads_ntstatus(rc); + goto done; + } + + count = ads_count_replies(ads, res); + if (count == 0) + break; + + if (num_members == 0) { + if (!ads_pull_uint32(ads, res, "usnChanged", &first_usn)) { + DEBUG(1, ("ads: lookup_groupmem could not pull usnChanged!\n")); + goto done; + } + } + + if (!ads_pull_uint32(ads, res, "usnChanged", ¤t_usn)) { + DEBUG(1, ("ads: lookup_groupmem could not pull usnChanged!\n")); + goto done; + } + + if (first_usn != current_usn) { + DEBUG(5, ("ads: lookup_groupmem USN on this record changed - restarting search\n")); + if (num_retries < 5) { + num_retries++; + num_members = 0; + continue; + } else { + DEBUG(5, ("ads: lookup_groupmem USN on this record changed - restarted search too many times, aborting!\n")); + status = NT_STATUS_UNSUCCESSFUL; + goto done; + } + } + + members = ads_pull_strings_range(ads, mem_ctx, res, + "member", + members, + &attrs[0], + &num_members, + &more_values); + + if ((members == NULL) || (num_members == 0)) + break; + + } while (more_values); + /* now we need to turn a list of members into rids, names and name types the problem is that the members are in the form of distinguised names */ - for (i=0;members[i];i++) /* noop */ ; - num_members = i; (*sid_mem) = talloc_zero(mem_ctx, sizeof(**sid_mem) * num_members); (*name_types) = talloc_zero(mem_ctx, sizeof(**name_types) * num_members); @@ -762,13 +812,13 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, status = NT_STATUS_OK; DEBUG(3,("ads lookup_groupmem for sid=%s\n", sid_to_string(sid_string, group_sid))); done: + if (res) ads_msgfree(ads, res); return status; } - /* find the sequence number for a domain */ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) { -- cgit From 81e028f4ace8eddab33ab2d76de1055b7dacc92e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:54:37 +0000 Subject: rpc_client/cli_lsarpc.c: rpc_parse/parse_lsa.c: nsswitch/winbindd_rpc.c: nsswitch/winbindd.h: - Add const libads/ads_ldap.c: - Add ads_sid_to_dn utility function nsswitch/winbindd_ads.c: - Use new utility function ads_sid_to_dn - Don't search for 'dn=', rather call the ads_search_retry_dn() nsswitch/winbindd_ads.c: include/rpc_ds.h: rpc_client/cli_ds.c: - Fixup braindamage in cli_ds_enum_domain_trusts(): - This function was returning a UNISTR2 up to the caller, and was doing nasty (invalid, per valgrind) things with memcpy() - Create a new structure that represents this informaiton in a useful way and use talloc. Andrew Bartlett (This used to be commit 627d33d1667f0d4b1070f988494885b74c4c04dd) --- source3/include/rpc_ds.h | 13 +++++ source3/libads/ads_ldap.c | 79 +++++++++++++++++++++++++++++ source3/nsswitch/winbindd.h | 2 +- source3/nsswitch/winbindd_ads.c | 110 +++++++++++++--------------------------- source3/nsswitch/winbindd_rpc.c | 2 +- source3/rpc_client/cli_ds.c | 34 ++++++++++--- source3/rpc_client/cli_lsarpc.c | 2 +- source3/rpc_parse/parse_lsa.c | 4 +- 8 files changed, 159 insertions(+), 87 deletions(-) diff --git a/source3/include/rpc_ds.h b/source3/include/rpc_ds.h index 4d3f5416ac..3cb7c64955 100644 --- a/source3/include/rpc_ds.h +++ b/source3/include/rpc_ds.h @@ -118,6 +118,19 @@ typedef struct { } DS_DOMAIN_TRUSTS; +struct ds_domain_trust { + /* static portion of structure */ + uint32 flags; + uint32 parent_index; + uint32 trust_type; + uint32 trust_attributes; + GUID guid; + + DOM_SID sid; + char *netbios_domain; + char *dns_domain; +}; + typedef struct { uint32 ptr; diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index dcceaaeb83..944cb1599c 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -152,4 +152,83 @@ done: return status; } + +/* convert a sid to a DN */ + +ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + char **dn) +{ + ADS_STATUS rc; + LDAPMessage *msg = NULL; + LDAPMessage *entry = NULL; + char *ldap_exp; + char *sidstr = NULL; + int count; + char *dn2 = NULL; + + const char *attr[] = { + "dn", + NULL + }; + + if (!(sidstr = sid_binstring(sid))) { + DEBUG(1,("ads_sid_to_dn: sid_binstring failed!\n")); + rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + goto done; + } + + if(!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr))) { + DEBUG(1,("ads_sid_to_dn: talloc_asprintf failed!\n")); + rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + goto done; + } + + rc = ads_search_retry(ads, (void **)&msg, ldap_exp, attr); + + if (!ADS_ERR_OK(rc)) { + DEBUG(1,("ads_sid_to_dn ads_search: %s\n", ads_errstr(rc))); + goto done; + } + + if ((count = ads_count_replies(ads, msg)) != 1) { + fstring sid_string; + DEBUG(1,("ads_sid_to_dn (sid=%s): Not found (count=%d)\n", + sid_to_string(sid_string, sid), count)); + rc = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); + goto done; + } + + entry = ads_first_entry(ads, msg); + + dn2 = ads_get_dn(ads, entry); + + if (!dn2) { + rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + goto done; + } + + *dn = talloc_strdup(mem_ctx, dn2); + + if (!*dn) { + ads_memfree(ads, dn2); + rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + goto done; + } + + rc = ADS_ERROR_NT(NT_STATUS_OK); + + DEBUG(3,("ads sid_to_dn mapped %s\n", dn2)); + + SAFE_FREE(dn2); +done: + if (msg) ads_msgfree(ads, msg); + if (dn2) ads_memfree(ads, dn2); + + SAFE_FREE(sidstr); + + return rc; +} + #endif diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index f1a58ab451..7c612ea61b 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -155,7 +155,7 @@ struct winbindd_methods { /* convert a sid to a user or group name */ NTSTATUS (*sid_to_name)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *sid, + const DOM_SID *sid, char **name, enum SID_NAME_USE *type); diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 6f382b6350..b6ca366abb 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -324,7 +324,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, /* convert a sid to a user or group name */ static NTSTATUS sid_to_name(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *sid, + const DOM_SID *sid, char **name, enum SID_NAME_USE *type) { @@ -350,24 +350,14 @@ static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *dn, char **name, uint32 *name_type, DOM_SID *sid) { - char *ldap_exp; void *res = NULL; const char *attrs[] = {"userPrincipalName", "sAMAccountName", "objectSid", "sAMAccountType", NULL}; ADS_STATUS rc; uint32 atype; - char *escaped_dn = escape_ldap_string_alloc(dn); - DEBUG(3,("ads: dn_lookup\n")); - if (!escaped_dn) { - return False; - } - - asprintf(&ldap_exp, "(distinguishedName=%s)", escaped_dn); - rc = ads_search_retry(ads, &res, ldap_exp, attrs); - SAFE_FREE(ldap_exp); - SAFE_FREE(escaped_dn); + rc = ads_search_retry_dn(ads, &res, dn, attrs); if (!ADS_ERR_OK(rc) || !res) { goto failed; @@ -487,6 +477,7 @@ static NTSTATUS lookup_usergroups_alt(struct winbindd_domain *domain, char *ldap_exp; ADS_STRUCT *ads; const char *group_attrs[] = {"objectSid", NULL}; + char *escaped_dn; DEBUG(3,("ads: lookup_usergroups_alt\n")); @@ -497,15 +488,24 @@ static NTSTATUS lookup_usergroups_alt(struct winbindd_domain *domain, goto done; } + if (!(escaped_dn = escape_ldap_string_alloc(user_dn))) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + /* buggy server, no tokenGroups. Instead lookup what groups this user is a member of by DN search on member*/ - if (asprintf(&ldap_exp, "(&(member=%s)(objectClass=group))", user_dn) == -1) { + + if (!(ldap_exp = talloc_asprintf(mem_ctx, "(&(member=%s)(objectClass=group))", escaped_dn))) { DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn)); - return NT_STATUS_NO_MEMORY; + SAFE_FREE(escaped_dn); + status = NT_STATUS_NO_MEMORY; + goto done; } - + + SAFE_FREE(escaped_dn); + rc = ads_search_retry(ads, &res, ldap_exp, group_attrs); - free(ldap_exp); if (!ADS_ERR_OK(rc) || !res) { DEBUG(1,("lookup_usergroups ads_search member=%s: %s\n", user_dn, ads_errstr(rc))); @@ -566,18 +566,15 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, uint32 *num_groups, DOM_SID ***user_gids) { ADS_STRUCT *ads = NULL; - const char *attrs[] = {"distinguishedName", NULL}; - const char *attrs2[] = {"tokenGroups", "primaryGroupID", NULL}; + const char *attrs[] = {"tokenGroups", "primaryGroupID", NULL}; ADS_STATUS rc; int count; - void *msg = NULL; - char *ldap_exp; + LDAPMessage *msg = NULL; char *user_dn; DOM_SID *sids; int i; DOM_SID *primary_group; uint32 primary_group_rid; - char *sidstr; fstring sid_string; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; @@ -588,44 +585,26 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, if (!ads) { domain->last_status = NT_STATUS_SERVER_DISABLED; + status = NT_STATUS_SERVER_DISABLED; goto done; } - if (!(sidstr = sid_binstring(sid))) { - DEBUG(1,("lookup_usergroups(sid=%s) sid_binstring returned NULL\n", sid_to_string(sid_string, sid))); - status = NT_STATUS_NO_MEMORY; - goto done; - } - if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { - free(sidstr); - DEBUG(1,("lookup_usergroups(sid=%s) asprintf failed!\n", sid_to_string(sid_string, sid))); - status = NT_STATUS_NO_MEMORY; - goto done; - } - - rc = ads_search_retry(ads, &msg, ldap_exp, attrs); - free(ldap_exp); - free(sidstr); - - if (!ADS_ERR_OK(rc) || !msg) { - DEBUG(1,("lookup_usergroups(sid=%s) ads_search: %s\n", sid_to_string(sid_string, sid), ads_errstr(rc))); + rc = ads_sid_to_dn(ads, mem_ctx, sid, &user_dn); + if (!ADS_ERR_OK(rc)) { + status = ads_ntstatus(rc); goto done; } - user_dn = ads_pull_string(ads, mem_ctx, msg, "distinguishedName"); - if (!user_dn) { - DEBUG(1,("lookup_usergroups(sid=%s) ads_search did not return a a distinguishedName!\n", sid_to_string(sid_string, sid))); - if (msg) - ads_msgfree(ads, msg); + rc = ads_search_retry_dn(ads, (void**)&msg, user_dn, attrs); + if (!ADS_ERR_OK(rc)) { + status = ads_ntstatus(rc); + DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: %s\n", sid_to_string(sid_string, sid), ads_errstr(rc))); goto done; } - - if (msg) - ads_msgfree(ads, msg); - - rc = ads_search_retry_dn(ads, &msg, user_dn, attrs2); - if (!ADS_ERR_OK(rc) || !msg) { - DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: %s\n", sid_to_string(sid_string, sid), ads_errstr(rc))); + + if (!msg) { + DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n", sid_to_string(sid_string, sid))); + status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -858,7 +837,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, DOM_SID **dom_sids) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DS_DOMAIN_TRUSTS *domains = NULL; + struct ds_domain_trust *domains = NULL; int count = 0; int i; struct cli_state *cli = NULL; @@ -876,7 +855,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, contact_domain_name = *domain->alt_name ? domain->alt_name : domain->name; if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(contact_domain_name, PI_NETLOGON, &cli)) ) { DEBUG(5, ("trusted_domains: Could not open a connection to %s for PIPE_NETLOGON (%s)\n", - contact_domain_name, nt_errstr(result))); + domain->name, nt_errstr(result))); return NT_STATUS_UNSUCCESSFUL; } @@ -908,27 +887,10 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, /* Copy across names and sids */ for (i = 0; i < count; i++) { - fstring tmp; - fstring tmp2; - - (*names)[i] = NULL; - (*alt_names)[i] = NULL; - ZERO_STRUCT( (*dom_sids)[i] ); + (*names)[i] = domains[i].netbios_domain; + (*alt_names)[i] = domains[i].dns_domain; - if ( domains[i].netbios_ptr ) { - unistr2_to_ascii(tmp, &domains[i].netbios_domain, sizeof(tmp) - 1); - (*names)[i] = talloc_strdup(mem_ctx, tmp); - } - - if ( domains[i].dns_ptr ) { - unistr2_to_ascii(tmp2, &domains[i].dns_domain, sizeof(tmp2) - 1); - (*alt_names)[i] = talloc_strdup(mem_ctx, tmp2); - } - - /* sometimes we will get back a NULL SID from this call */ - - if ( domains[i].sid_ptr ) - sid_copy(&(*dom_sids)[i], &domains[i].sid.sid); + sid_copy(&(*dom_sids)[i], &domains[i].sid); } *num_domains = count; @@ -936,8 +898,6 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, done: - SAFE_FREE( domains ); - /* remove connection; This is a special case to the \NETLOGON pipe */ if ( cli ) diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 916ae78d21..79724e2d20 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -323,7 +323,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, */ static NTSTATUS sid_to_name(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *sid, + const DOM_SID *sid, char **name, enum SID_NAME_USE *type) { diff --git a/source3/rpc_client/cli_ds.c b/source3/rpc_client/cli_ds.c index a7a093328c..f8455edcd9 100644 --- a/source3/rpc_client/cli_ds.c +++ b/source3/rpc_client/cli_ds.c @@ -82,7 +82,7 @@ done: NTSTATUS cli_ds_enum_domain_trusts(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *server, uint32 flags, - DS_DOMAIN_TRUSTS **trusts, uint32 *num_domains) + struct ds_domain_trust **trusts, uint32 *num_domains) { prs_struct qbuf, rbuf; DS_Q_ENUM_DOM_TRUSTS q; @@ -118,12 +118,32 @@ NTSTATUS cli_ds_enum_domain_trusts(struct cli_state *cli, TALLOC_CTX *mem_ctx, int i; *num_domains = r.num_domains; - *trusts = (DS_DOMAIN_TRUSTS*)smb_xmalloc(r.num_domains*sizeof(DS_DOMAIN_TRUSTS)); - - memcpy( *trusts, r.domains.trusts, r.num_domains*sizeof(DS_DOMAIN_TRUSTS) ); - for ( i=0; i Date: Tue, 6 Jan 2004 00:05:31 +0000 Subject: (merge from 3.0) Change (unused) structure parameter for cli_ds_enum_domain_trusts() cleanup. Andrew Bartlett (This used to be commit 3c02aad8b3a4b28ca492ca1abbbd594ba75975e4) --- source3/rpcclient/cmd_ds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpcclient/cmd_ds.c b/source3/rpcclient/cmd_ds.c index b01236d9a5..c5b12ed150 100644 --- a/source3/rpcclient/cmd_ds.c +++ b/source3/rpcclient/cmd_ds.c @@ -53,7 +53,7 @@ static NTSTATUS cmd_ds_enum_domain_trusts(struct cli_state *cli, { NTSTATUS result; uint32 flags = 0x1; - DS_DOMAIN_TRUSTS *trusts = NULL; + struct ds_domain_trust *trusts = NULL; unsigned int num_domains = 0; result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost, flags, -- cgit From 9925ab72f0274aee8c13567b22a37289474af751 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 00:06:49 +0000 Subject: (merge from 3.0) There is some memory corruption hidden somewhere in our winbind code. If I could reproduce it, I would fix it, but for now just make sure we always SAFE_FREE() and set our starting pointers to NULL. Andrew Bartlett (This used to be commit a00f29624d10df7f31fa978b79bc71b40d696359) --- source3/libads/ldap_utils.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 4142bceabc..991f16c845 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -35,6 +35,8 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope int count = 3; char *bp; + *res = NULL; + if (!ads->ld && time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) { return ADS_ERROR(LDAP_SERVER_DOWN); @@ -42,15 +44,17 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope bp = strdup(bind_path); - if (!bp) + if (!bp) { return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } while (count--) { + *res = NULL; status = ads_do_search_all(ads, bp, scope, expr, attrs, res); if (ADS_ERR_OK(status)) { DEBUG(5,("Search for %s gave %d replies\n", expr, ads_count_replies(ads, *res))); - free(bp); + SAFE_FREE(bp); return status; } @@ -72,11 +76,11 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", ads_errstr(status))); ads_destroy(&ads); - free(bp); + SAFE_FREE(bp); return status; } } - free(bp); + SAFE_FREE(bp); if (!ADS_ERR_OK(status)) DEBUG(1,("ads reopen failed after error %s\n", -- cgit From a9598d2e88fcd5384640baa963000e4f02679985 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 00:08:53 +0000 Subject: (merge from 3.0) Add const. Andrew Bartlett (This used to be commit b08502a8fb1083cc49fd2976880b7bef3f14a72a) --- source3/nsswitch/winbindd_cache.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index bc6967dee1..91ef38a368 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -585,7 +585,7 @@ static void centry_end(struct cache_entry *centry, const char *format, ...) static void wcache_save_name_to_sid(struct winbindd_domain *domain, NTSTATUS status, - const char *name, DOM_SID *sid, + const char *name, const DOM_SID *sid, enum SID_NAME_USE type) { struct cache_entry *centry; @@ -604,7 +604,7 @@ static void wcache_save_name_to_sid(struct winbindd_domain *domain, } static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status, - DOM_SID *sid, const char *name, enum SID_NAME_USE type) + const DOM_SID *sid, const char *name, enum SID_NAME_USE type) { struct cache_entry *centry; fstring sid_string; @@ -972,7 +972,7 @@ do_query: given */ static NTSTATUS sid_to_name(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *sid, + const DOM_SID *sid, char **name, enum SID_NAME_USE *type) { -- cgit From eb1aa6a2cc0331cbbbc5ea466e5695e4df39e6ee Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 00:13:56 +0000 Subject: (merge from 3.0) Change our Domain controller lookup routines to more carefully seperate DNS names (realms) from NetBIOS domain names. Until now, we would experience delays as we broadcast lookups for DNS names onto the local network segments. Now if DNS comes back negative, we fall straight back to looking up the short name. Andrew Bartlett (This used to be commit 4c3bd0a99e464198d243da302ff1868189b4dcff) --- source3/auth/auth_domain.c | 7 ++- source3/libsmb/namequery_dc.c | 27 ++++----- source3/libsmb/trusts_util.c | 2 +- source3/nsswitch/winbindd_ads.c | 4 +- source3/nsswitch/winbindd_cm.c | 61 +++++++++----------- source3/nsswitch/winbindd_misc.c | 14 ++++- source3/nsswitch/winbindd_pam.c | 118 ++++++++++++++++++++++++--------------- source3/nsswitch/winbindd_rpc.c | 22 ++++---- source3/nsswitch/winbindd_util.c | 10 ++-- 9 files changed, 144 insertions(+), 121 deletions(-) diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 43e7597cd9..0f34bcc0e2 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -165,6 +165,9 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, if ( !NT_STATUS_IS_OK(nt_status) ) { DEBUG(0,("domain_client_validate: Domain password server not available.\n")); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { + return NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE; + } return nt_status; } @@ -290,7 +293,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, /* we need our DC to send the net_sam_logon() request to */ - if ( !get_dc_name(domain, dc_name, &dc_ip) ) { + if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) { DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n", user_info->domain.str)); return NT_STATUS_NO_LOGON_SERVERS; @@ -385,7 +388,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte /* use get_dc_name() for consistency even through we know that it will be a netbios name */ - if ( !get_dc_name(user_info->domain.str, dc_name, &dc_ip) ) { + if ( !get_dc_name(user_info->domain.str, NULL, dc_name, &dc_ip) ) { DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n", user_info->domain.str)); return NT_STATUS_NO_LOGON_SERVERS; diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index df7f856cd7..31d759e0d2 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -29,27 +29,23 @@ Find the name and IP address for a server in he realm/domain *************************************************************************/ -static BOOL ads_dc_name(const char *domain, struct in_addr *dc_ip, fstring srv_name) +static BOOL ads_dc_name(const char *domain, const char *realm, struct in_addr *dc_ip, fstring srv_name) { ADS_STRUCT *ads; - const char *realm = domain; - if (strequal(realm, lp_workgroup())) + if (!realm && strequal(domain, lp_workgroup())) realm = lp_realm(); ads = ads_init(realm, domain, NULL); if (!ads) return False; - /* we don't need to bind, just connect */ - ads->auth.flags |= ADS_AUTH_NO_BIND; - DEBUG(4,("ads_dc_name: domain=%s\n", domain)); #ifdef HAVE_ADS - /* a full ads_connect() is actually overkill, as we don't srictly need - to do the SASL auth in order to get the info we need, but libads - doesn't offer a better way right now */ + /* we don't need to bind, just connect */ + ads->auth.flags |= ADS_AUTH_NO_BIND; + ads_connect(ads); #endif @@ -157,7 +153,7 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip wrapper around ads and rpc methods of finds DC's **********************************************************************/ -BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) +BOOL get_dc_name(const char *domain, const char *realm, fstring srv_name, struct in_addr *ip_out) { struct in_addr dc_ip; BOOL ret; @@ -167,15 +163,14 @@ BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) ret = False; - if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), domain) ) + if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), realm) ) our_domain = True; - /* always try to obey what the admin specified in smb.conf. - If it is not our domain, assume that domain names with periods - in them are realm names */ + /* always try to obey what the admin specified in smb.conf + (for the local domain) */ - if ( (our_domain && lp_security()==SEC_ADS) || strchr_m(domain, '.') ) { - ret = ads_dc_name(domain, &dc_ip, srv_name); + if ( (our_domain && lp_security()==SEC_ADS) || realm ) { + ret = ads_dc_name(domain, realm, &dc_ip, srv_name); } if (!ret) { diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 7c1000b9a5..b420e4fa08 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -144,7 +144,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* lookup a DC first */ - if ( !get_dc_name(domain, dc_name, &dc_ip) ) { + if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) { DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n", domain)); return False; diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index b6ca366abb..889f63a42c 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -843,7 +843,6 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, struct cli_state *cli = NULL; /* i think we only need our forest and downlevel trusted domains */ uint32 flags = DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND; - char *contact_domain_name; DEBUG(3,("ads: trusted_domains\n")); @@ -852,8 +851,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, *names = NULL; *dom_sids = NULL; - contact_domain_name = *domain->alt_name ? domain->alt_name : domain->name; - if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(contact_domain_name, PI_NETLOGON, &cli)) ) { + if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(domain, PI_NETLOGON, &cli)) ) { DEBUG(5, ("trusted_domains: Could not open a connection to %s for PIPE_NETLOGON (%s)\n", domain->name, nt_errstr(result))); return NT_STATUS_UNSUCCESSFUL; diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 0630403cbc..ebf342b355 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -112,8 +112,8 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password) /* Open a connction to the remote server, cache failures for 30 seconds */ -static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, - struct winbindd_cm_conn *new_conn) +static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const int pipe_index, + struct winbindd_cm_conn *new_conn) { NTSTATUS result; char *machine_password; @@ -124,21 +124,22 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, ZERO_STRUCT(dc_ip); - fstrcpy(new_conn->domain, domain); - fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index)); + fstrcpy(new_conn->domain, domain->name); /* connection failure cache has been moved inside of get_dc_name so we can deal with half dead DC's --jerry */ - if (!get_dc_name(domain, new_conn->controller, &dc_ip)) { + if (!get_dc_name(domain->name, domain->alt_name[0] ? domain->alt_name : NULL, + new_conn->controller, &dc_ip)) { result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; - add_failed_connection_entry(domain, "", result); + add_failed_connection_entry(domain->name, "", result); return result; } /* Initialise SMB connection */ + fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index)); - /* grab stored passwords */ +/* grab stored passwords */ machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(), lp_realm()) == -1) { @@ -180,7 +181,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, if (!NT_STATUS_IS_OK(result = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal, machine_password, - domain))) { + domain->name))) { DEBUG(4,("failed kerberos session setup with %s\n", nt_errstr(result))); if (NT_STATUS_IS_OK(result)) result = NT_STATUS_UNSUCCESSFUL; @@ -202,7 +203,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, if (!cli_session_setup(new_conn->cli, ipc_username, ipc_password, strlen(ipc_password)+1, ipc_password, strlen(ipc_password)+1, - domain)) { + domain->name)) { result = cli_nt_error(new_conn->cli); DEBUG(4,("failed authenticated session setup with %s\n", nt_errstr(result))); if (NT_STATUS_IS_OK(result)) @@ -259,13 +260,13 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, SAFE_FREE(machine_password); if (!NT_STATUS_IS_OK(result)) { - add_failed_connection_entry(domain, new_conn->controller, result); + add_failed_connection_entry(domain->name, new_conn->controller, result); return result; } /* set the domain if empty; needed for schannel connections */ if ( !*new_conn->cli->domain ) - fstrcpy( new_conn->cli->domain, domain ); + fstrcpy( new_conn->cli->domain, domain->name ); if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) { @@ -279,7 +280,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, * specific UUID right now, i'm not going to bother. --jerry */ if ( !is_win2k_pipe(pipe_index) ) - add_failed_connection_entry(domain, new_conn->controller, result); + add_failed_connection_entry(domain->name, new_conn->controller, result); cli_shutdown(new_conn->cli); return result; } @@ -292,7 +293,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, setup cli_state struct ************************************************************************/ -NTSTATUS cm_fresh_connection(const char *domain, const int pipe_index, +NTSTATUS cm_fresh_connection(struct winbindd_domain *domain, const int pipe_index, struct cli_state **cli) { NTSTATUS result; @@ -339,13 +340,13 @@ static BOOL connection_ok(struct winbindd_cm_conn *conn) /* Search the cache for a connection. If there is a broken one, shut it down properly and return NULL. */ -static void find_cm_connection(const char *domain, const char *pipe_name, +static void find_cm_connection(struct winbindd_domain *domain, const char *pipe_name, struct winbindd_cm_conn **conn_out) { struct winbindd_cm_conn *conn; for (conn = cm_conns; conn; ) { - if (strequal(conn->domain, domain) && + if (strequal(conn->domain, domain->name) && strequal(conn->pipe_name, pipe_name)) { if (!connection_ok(conn)) { /* Dead connection - remove it. */ @@ -368,7 +369,7 @@ static void find_cm_connection(const char *domain, const char *pipe_name, /* Initialize a new connection up to the RPC BIND. */ -static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name, +static NTSTATUS new_cm_connection(struct winbindd_domain *domain, const char *pipe_name, struct winbindd_cm_conn **conn_out) { struct winbindd_cm_conn *conn; @@ -381,7 +382,7 @@ static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name, if (!NT_STATUS_IS_OK(result = cm_open_connection(domain, get_pipe_index(pipe_name), conn))) { DEBUG(3, ("Could not open a connection to %s for %s (%s)\n", - domain, pipe_name, nt_errstr(result))); + domain->name, pipe_name, nt_errstr(result))); SAFE_FREE(conn); return result; } @@ -393,7 +394,7 @@ static NTSTATUS new_cm_connection(const char *domain, const char *pipe_name, /* Get a connection to the remote DC and open the pipe. If there is already a connection, use that */ -static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_name, +static NTSTATUS get_connection_from_cache(struct winbindd_domain *domain, const char *pipe_name, struct winbindd_cm_conn **conn_out) { find_cm_connection(domain, pipe_name, conn_out); @@ -407,7 +408,7 @@ static NTSTATUS get_connection_from_cache(const char *domain, const char *pipe_n /********************************************************************************** **********************************************************************************/ -BOOL cm_check_for_native_mode_win2k( const char *domain ) +BOOL cm_check_for_native_mode_win2k( struct winbindd_domain *domain ) { NTSTATUS result; struct winbindd_cm_conn conn; @@ -420,7 +421,7 @@ BOOL cm_check_for_native_mode_win2k( const char *domain ) if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) { DEBUG(5, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n", - domain, nt_errstr(result))); + domain->name, nt_errstr(result))); return False; } @@ -451,7 +452,7 @@ done: /* Return a LSA policy handle on a domain */ -NTSTATUS cm_get_lsa_handle(const char *domain, CLI_POLICY_HND **return_hnd) +NTSTATUS cm_get_lsa_handle(struct winbindd_domain *domain, CLI_POLICY_HND **return_hnd) { struct winbindd_cm_conn *conn; uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; @@ -504,7 +505,7 @@ NTSTATUS cm_get_lsa_handle(const char *domain, CLI_POLICY_HND **return_hnd) /* Return a SAM policy handle on a domain */ -NTSTATUS cm_get_sam_handle(char *domain, CLI_POLICY_HND **return_hnd) +NTSTATUS cm_get_sam_handle(struct winbindd_domain *domain, CLI_POLICY_HND **return_hnd) { struct winbindd_cm_conn *conn; uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; @@ -562,7 +563,7 @@ NTSTATUS cm_get_sam_handle(char *domain, CLI_POLICY_HND **return_hnd) /* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the netlogon pipe as no handle is returned. */ -NTSTATUS cm_get_netlogon_cli(const char *domain, +NTSTATUS cm_get_netlogon_cli(struct winbindd_domain *domain, const unsigned char *trust_passwd, uint32 sec_channel_type, BOOL fresh, @@ -572,7 +573,6 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, struct winbindd_cm_conn *conn; fstring lock_name; BOOL got_mutex; - struct winbindd_domain *wb_domain = NULL; if (!cli) return NT_STATUS_INVALID_PARAMETER; @@ -614,16 +614,9 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, if ( sec_channel_type == SEC_CHAN_DOMAIN ) fstr_sprintf(conn->cli->mach_acct, "%s$", lp_workgroup()); - /* we need the short form of the domain name for the schanel - rpc bind. What if we fail? I don't think we should ever get - a request for a domain name not in our list but I'm not bailing - out if we do since I'm not 10% certain about this --jerry */ - - if ( (wb_domain = find_domain_from_name( domain )) != NULL ) { - DEBUG(5,("cm_get_netlogon_cli: Using short for of domain name [%s] for netlogon rpc bind\n", - wb_domain->name)); - fstrcpy( conn->cli->domain, wb_domain->name); - } + + fstrcpy( conn->cli->domain, domain->name); + result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd); diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c index 1a5ecb56c7..19beddc304 100644 --- a/source3/nsswitch/winbindd_misc.c +++ b/source3/nsswitch/winbindd_misc.c @@ -36,7 +36,8 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat struct cli_state *cli; uint32 sec_channel_type; const char *contact_domain_name = NULL; - + struct winbindd_domain *contact_domain; + DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid)); /* Get trust account password */ @@ -56,12 +57,19 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat if ( !contact_domain_name || !*contact_domain_name ) contact_domain_name = lp_workgroup(); - + + contact_domain = find_domain_from_name(contact_domain_name); + if (!contact_domain) { + result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + DEBUG(1, ("%s is not a trusted domain\n", contact_domain_name)); + goto done; + } + /* This call does a cli_nt_setup_creds() which implicitly checks the trust account password. */ /* Don't shut this down - it belongs to the connection cache code */ - result = cm_get_netlogon_cli(contact_domain_name, + result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, True, &cli); if (!NT_STATUS_IS_OK(result)) { diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 3ca91b1c07..801f36df79 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -74,7 +74,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; + struct winbindd_domain *contact_domain; BOOL retry; /* Ensure null termination */ @@ -106,21 +106,15 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response)); nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response)); - if ( !get_trust_pw(name_domain, trust_passwd, &last_change_time, &sec_channel_type) ) { - result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - goto done; - } - /* what domain should we contact? */ if ( IS_DC ) { - if (!find_domain_from_name(name_domain)) { - DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", + if (!(contact_domain = find_domain_from_name(name_domain))) { + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", state->request.data.auth.user, name_domain, name_user, name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - contact_domain = name_domain; } else { if (is_myname(name_domain)) { @@ -128,8 +122,20 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) result = NT_STATUS_NO_SUCH_USER; goto done; } - contact_domain = lp_workgroup(); + + if (!(contact_domain = find_our_domain())) { + DEBUG(1, ("Authenticatoin for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n", + state->request.data.auth.user, name_domain, name_user)); + result = NT_STATUS_NO_SUCH_USER; + goto done; + } + } + + if ( !get_trust_pw(contact_domain->name, trust_passwd, &last_change_time, &sec_channel_type) ) { + result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + goto done; } + /* check authentication loop */ do { @@ -193,7 +199,10 @@ done: state->response.data.auth.nt_status = NT_STATUS_V(result); fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); + + /* we might have given a more useful error above */ + if (!*state->response.data.auth.error_string) + fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); state->response.data.auth.pam_error = nt_status_to_pam(result); DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n", @@ -220,10 +229,10 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) NET_USER_INFO_3 info3; struct cli_state *cli = NULL; TALLOC_CTX *mem_ctx = NULL; - char *user = NULL; - const char *domain = NULL; + char *name_user = NULL; + const char *name_domain = NULL; const char *workstation; - const char *contact_domain; + struct winbindd_domain *contact_domain; DOM_CRED ret_creds; int attempts = 0; BOOL retry; @@ -254,7 +263,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) goto done; } - if (pull_utf8_talloc(mem_ctx, &user, state->request.data.auth_crap.user) == (size_t)-1) { + if (pull_utf8_talloc(mem_ctx, &name_user, state->request.data.auth_crap.user) == (size_t)-1) { DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; @@ -267,24 +276,19 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) result = NT_STATUS_UNSUCCESSFUL; goto done; } - domain = dom; + name_domain = dom; } else if (lp_winbind_use_default_domain()) { - domain = lp_workgroup(); + name_domain = lp_workgroup(); } else { DEBUG(5,("no domain specified with username (%s) - failing auth\n", - user)); - result = NT_STATUS_INVALID_PARAMETER; + name_user)); + result = NT_STATUS_NO_SUCH_USER; goto done; } DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid, - domain, user)); + name_domain, name_user)); - if ( !get_trust_pw(domain, trust_passwd, &last_change_time, &sec_channel_type) ) { - result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - goto done; - } - if (*state->request.data.auth_crap.workstation) { char *wrk = NULL; if (pull_utf8_talloc(mem_ctx, &wrk, state->request.data.auth_crap.workstation) == (size_t)-1) { @@ -309,25 +313,39 @@ 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? */ + + /* what domain should we contact? */ if ( IS_DC ) { - if (!find_domain_from_name(domain)) { - DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", - state->request.data.auth.user, domain, user, domain)); + if (!(contact_domain = find_domain_from_name(name_domain))) { + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request.data.auth.user, name_domain, name_user, name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - contact_domain = domain; + } else { - if (is_myname(domain)) { - DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", domain)); + if (is_myname(name_domain)) { + DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - contact_domain = lp_workgroup(); + + if (!(contact_domain = find_our_domain())) { + DEBUG(1, ("Authenticatoin for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n", + state->request.data.auth.user, name_domain, name_user)); + result = NT_STATUS_NO_SUCH_USER; + goto done; + } } + if ( !get_trust_pw(contact_domain->name, trust_passwd, &last_change_time, &sec_channel_type) ) { + result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + goto done; + } + do { ZERO_STRUCT(info3); ZERO_STRUCT(ret_creds); @@ -344,7 +362,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) result = cli_netlogon_sam_network_logon(cli, mem_ctx, &ret_creds, - user, domain, + name_user, name_domain, workstation, state->request.data.auth_crap.chal, lm_resp, nt_resp, @@ -368,7 +386,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) ) { DEBUG(3,("winbindd_pam_auth_crap: sam_logon returned ACCESS_DENIED. Maybe the trust account " "password was changed and we didn't know it. Killing connections to domain %s\n", - domain)); + contact_domain->name)); winbindd_cm_flush(); retry = True; cli = NULL; @@ -380,7 +398,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) if (NT_STATUS_IS_OK(result)) { netsamlogon_cache_store( cli->mem_ctx, &info3 ); - wcache_invalidate_samlogon(find_domain_from_name(domain), &info3); + wcache_invalidate_samlogon(find_domain_from_name(name_domain), &info3); if (state->request.flags & WBFLAG_PAM_INFO3_NDR) { result = append_info3_as_ndr(mem_ctx, state, &info3); @@ -392,12 +410,12 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) const char *nt_username, *nt_domain; if (!(nt_username = unistr2_tdup(mem_ctx, &(info3.uni_user_name)))) { /* If the server didn't give us one, just use the one we sent them */ - nt_username = user; + nt_username = name_user; } if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3.uni_logon_dom)))) { /* If the server didn't give us one, just use the one we sent them */ - nt_domain = domain; + nt_domain = name_domain; } fill_domain_username(username_out, nt_domain, nt_username); @@ -436,8 +454,8 @@ done: DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n", - domain, - user, + name_domain, + name_user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); @@ -455,10 +473,19 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) char *oldpass, *newpass; fstring domain, user; CLI_POLICY_HND *hnd; + TALLOC_CTX *mem_ctx; + struct winbindd_domain *contact_domain; DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid, state->request.data.chauthtok.user)); + if (!(mem_ctx = talloc_init("winbind password change for (utf8) %s", + state->request.data.chauthtok.user))) { + DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n")); + result = NT_STATUS_NO_MEMORY; + goto done; + } + /* Setup crap */ if (state == NULL) @@ -466,7 +493,7 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) parse_domain_user(state->request.data.chauthtok.user, domain, user); - if (!find_domain_from_name(domain)) { + if (!(contact_domain = find_domain_from_name(domain))) { DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", state->request.data.chauthtok.user, domain, user, domain)); result = NT_STATUS_NO_SUCH_USER; @@ -480,17 +507,15 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) /* Get sam handle */ - if ( NT_STATUS_IS_ERR(result = cm_get_sam_handle(domain, &hnd)) ) { + if ( NT_STATUS_IS_ERR(result = cm_get_sam_handle(contact_domain, &hnd)) ) { DEBUG(1, ("could not get SAM handle on DC for %s\n", domain)); goto done; } - if (!cli_oem_change_password(hnd->cli, user, newpass, oldpass)) { + if (!NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(hnd->cli, mem_ctx, + user, newpass, oldpass))) { DEBUG(1, ("password change failed for user %s/%s\n", domain, user)); - result = NT_STATUS_WRONG_PASSWORD; - } else { - result = NT_STATUS_OK; } done: @@ -506,5 +531,8 @@ done: state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); + if (mem_ctx) + talloc_destroy(mem_ctx); + return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 79724e2d20..81bbc774d1 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -52,7 +52,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, do { /* Get sam handle */ - if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) ) + if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) ) return result; /* Get domain handle */ @@ -162,7 +162,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, retry = 0; do { - if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) return result; status = cli_samr_open_domain(hnd->cli, mem_ctx, @@ -227,7 +227,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain, retry = 0; do { - if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) ) + if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) ) return result; result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol, @@ -299,7 +299,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, retry = 0; do { - if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) { + if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd))) { return result; } @@ -339,7 +339,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, retry = 0; do { - if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd))) return result; result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol, @@ -408,7 +408,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain, do { /* Get sam handle; if we fail here there is no hope */ - if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) goto done; /* Get domain handle */ @@ -509,7 +509,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, do { /* Get sam handle; if we fail here there is no hope */ - if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) goto done; /* Get domain handle */ @@ -597,7 +597,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, retry = 0; do { /* Get sam handle */ - if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) goto done; /* Get domain handle */ @@ -875,7 +875,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) } #endif /* HAVE_LDAP */ /* Get sam handle */ - if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd))) goto done; /* Get domain handle */ @@ -931,7 +931,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, retry = 0; do { - if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(lp_workgroup(), &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(find_our_domain(), &hnd))) goto done; result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, @@ -960,7 +960,7 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid) retry = 0; do { /* Get lsa handle */ - if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) + if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd))) goto done; result = cli_lsa_query_info_policy(hnd->cli, mem_ctx, diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 0f14a7e413..95aaec3b1e 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -81,7 +81,6 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const DOM_SID *sid) { struct winbindd_domain *domain; - char *contact_name; const char *alternative_name = NULL; /* ignore alt_name if we are not in an AD domain */ @@ -134,12 +133,11 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const sid_copy(&domain->sid, sid); } - /* see if this is a native mode win2k domain (use realm name if possible) */ + /* see if this is a native mode win2k domain */ - contact_name = *domain->alt_name ? domain->alt_name : domain->name; - domain->native_mode = cm_check_for_native_mode_win2k( contact_name ); + domain->native_mode = cm_check_for_native_mode_win2k( domain ); - DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", contact_name, + DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain->name, domain->native_mode ? "native" : "mixed (or NT4)" )); /* Link to domain list */ @@ -297,7 +295,7 @@ BOOL init_domain_list(void) * * @note Do *not* pass lp_workgroup() to this function. domain_list * may modify it's value, and free that pointer. Instead, our local - * domain may be found by looking at the first entry in domain_list() + * domain may be found by calling find_our_domain(). * directly. * * -- cgit From 523a4ddd5fb851d86b50238ca4d22b98c2159c50 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 00:27:34 +0000 Subject: (merge from 3.0) Try to keep vl happy - shorten some of these lines. -- Grumble... grumble... fix the build... -- Show the sid type in name->sid translatons in a way that can be easily understood by humans. Andrew Bartlett (This used to be commit c5d1e2112baa7d87cd6b9f0855c2fd8b006af01d) --- source3/libads/ldap.c | 18 ++++++++++++------ source3/nsswitch/wbinfo.c | 2 +- source3/nsswitch/winbindd_ads.c | 21 ++++++++++++++------- source3/nsswitch/winbindd_pam.c | 12 +++++++----- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8aaca01bbf..79f267a6a8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1668,7 +1668,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, &range_start) == 1) { *more_strings = False; } else { - DEBUG(1, ("ads_pull_strings_range: Cannot parse Range attriubte (%s)\n", range_attr)); + DEBUG(1, ("ads_pull_strings_range: Cannot parse Range attriubte (%s)\n", + range_attr)); ldap_memfree(range_attr); *more_strings = False; return NULL; @@ -1676,7 +1677,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, } if ((*num_strings) != range_start) { - DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu - aborting range retreival\n", + DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu" + " - aborting range retreival\n", range_attr, *num_strings + 1, range_start)); ldap_memfree(range_attr); *more_strings = False; @@ -1686,8 +1688,10 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, new_strings = ads_pull_strings(ads, mem_ctx, msg, range_attr, &num_new_strings); if (*more_strings && ((*num_strings + num_new_strings) != (range_end + 1))) { - DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) tells us we have %lu strings in this bunch, but we only got %lu - aborting range retreival\n", - range_attr, (unsigned long int)range_end - range_start + 1, (unsigned long int)num_new_strings)); + DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) tells us we have %lu " + "strings in this bunch, but we only got %lu - aborting range retreival\n", + range_attr, (unsigned long int)range_end - range_start + 1, + (unsigned long int)num_new_strings)); ldap_memfree(range_attr); *more_strings = False; return NULL; @@ -1992,7 +1996,8 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) p = strchr(value, ':'); if (!p) { talloc_destroy(ctx); - DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' so was deemed invalid\n")); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' " + "so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -2002,7 +2007,8 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { talloc_destroy(ctx); - DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@' so was deemed invalid\n", ads->config.ldap_server_name)); + DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@'" + " so was deemed invalid\n", ads->config.ldap_server_name)); SAFE_FREE(ads->config.ldap_server_name); return ADS_ERROR(LDAP_DECODING_ERROR); } diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index bca1813167..55eeb9fa39 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -451,7 +451,7 @@ static BOOL wbinfo_lookupname(char *name) /* Display response */ - d_printf("%s %d\n", response.data.sid.sid, response.data.sid.type); + d_printf("%s %s (%d)\n", response.data.sid.sid, sid_type_lookup(response.data.sid.type), response.data.sid.type); return True; } diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 889f63a42c..f8582aee99 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -598,18 +598,21 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, rc = ads_search_retry_dn(ads, (void**)&msg, user_dn, attrs); if (!ADS_ERR_OK(rc)) { status = ads_ntstatus(rc); - DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: %s\n", sid_to_string(sid_string, sid), ads_errstr(rc))); + DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: %s\n", + sid_to_string(sid_string, sid), ads_errstr(rc))); goto done; } if (!msg) { - DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n", sid_to_string(sid_string, sid))); + DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n", + sid_to_string(sid_string, sid))); status = NT_STATUS_UNSUCCESSFUL; goto done; } if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group_rid)) { - DEBUG(1,("%s: No primary group for sid=%s !?\n", domain->name, sid_to_string(sid_string, sid))); + DEBUG(1,("%s: No primary group for sid=%s !?\n", + domain->name, sid_to_string(sid_string, sid))); goto done; } @@ -677,7 +680,8 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, uint32 current_usn; int num_retries = 0; - DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, sid_string_static(group_sid))); + DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, + sid_string_static(group_sid))); *num_names = 0; @@ -738,13 +742,15 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, } if (first_usn != current_usn) { - DEBUG(5, ("ads: lookup_groupmem USN on this record changed - restarting search\n")); + DEBUG(5, ("ads: lookup_groupmem USN on this record changed" + " - restarting search\n")); if (num_retries < 5) { num_retries++; num_members = 0; continue; } else { - DEBUG(5, ("ads: lookup_groupmem USN on this record changed - restarted search too many times, aborting!\n")); + DEBUG(5, ("ads: lookup_groupmem USN on this record changed" + " - restarted search too many times, aborting!\n")); status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -858,7 +864,8 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, } if ( NT_STATUS_IS_OK(result) ) - result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost, flags, &domains, (unsigned int *)&count ); + result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost, + flags, &domains, (unsigned int *)&count ); if ( NT_STATUS_IS_OK(result) && count) { diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 801f36df79..dba2fe8ba4 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -512,11 +512,13 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) goto done; } - if (!NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(hnd->cli, mem_ctx, - user, newpass, oldpass))) { - DEBUG(1, ("password change failed for user %s/%s\n", domain, - user)); - } + if (!cli_oem_change_password(hnd->cli, user, newpass, oldpass)) { + DEBUG(1, ("password change failed for user %s/%s\n", domain, + user)); + result = NT_STATUS_WRONG_PASSWORD; + } else { + result = NT_STATUS_OK; + } done: state->response.data.auth.nt_status = NT_STATUS_V(result); -- cgit From 06843fdee216a8b40fd44377f520a5c2345b0382 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 00:41:13 +0000 Subject: (merge from 3.0) Ensure that for wbinfo --set-auth-user, we actually use the domain. Andrew Bartlett (This used to be commit 8a63bed29315acb3fe9cc2973426ef8392987c8c) --- source3/nsswitch/winbindd_cm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index ebf342b355..c255d21102 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -181,7 +181,7 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i if (!NT_STATUS_IS_OK(result = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal, machine_password, - domain->name))) { + lp_workgroup()))) { DEBUG(4,("failed kerberos session setup with %s\n", nt_errstr(result))); if (NT_STATUS_IS_OK(result)) result = NT_STATUS_UNSUCCESSFUL; @@ -203,7 +203,7 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i if (!cli_session_setup(new_conn->cli, ipc_username, ipc_password, strlen(ipc_password)+1, ipc_password, strlen(ipc_password)+1, - domain->name)) { + ipc_domain)) { result = cli_nt_error(new_conn->cli); DEBUG(4,("failed authenticated session setup with %s\n", nt_errstr(result))); if (NT_STATUS_IS_OK(result)) -- cgit From 870105d74fe814ae839ee4962d00381e78fbef20 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 01:15:13 +0000 Subject: (merge from 3.0) Always call the auto-init funciton - this avoids tdb segfaulting under us if we failed to open it earlier. Andrew Bartlett (This used to be commit 34f16eaeaa81a0cc6ae564f4be8a02752ee5624d) --- source3/lib/gencache.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index da8808af16..39e727c24f 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -357,6 +357,9 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time int gencache_lock_entry( const char *key ) { + if (!gencache_init()) + return -1; + return tdb_lock_bystring(cache, key, 0); } @@ -366,6 +369,9 @@ int gencache_lock_entry( const char *key ) void gencache_unlock_entry( const char *key ) { + if (!gencache_init()) + return; + tdb_unlock_bystring(cache, key); return; } -- cgit From 35f843a1be9a703328eee3241bc24416cca945e0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 01:20:01 +0000 Subject: (merge from 3.0) I think this was tpot's originally: Fix format types for 64 bit systems. Andrew Bartlett (This used to be commit 256b2da7c96e8313f4f98ce700fc7634eaccb72b) --- source3/torture/denytest.c | 2 +- source3/torture/torture.c | 24 ++++++++++++++---------- source3/torture/utable.c | 4 ++-- source3/utils/ntlm_auth.c | 4 ++-- source3/utils/smbcontrol.c | 3 ++- source3/utils/smbfilter.c | 2 +- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/source3/torture/denytest.c b/source3/torture/denytest.c index 3a7906fb33..89b0fdf93f 100644 --- a/source3/torture/denytest.c +++ b/source3/torture/denytest.c @@ -1427,7 +1427,7 @@ BOOL torture_denytest1(int dummy) cli_close(cli1, fnum1); } - printf("testing %d entries\n", ARRAY_SIZE(denytable1)); + printf("testing %ld entries\n", (unsigned long)ARRAY_SIZE(denytable1)); for (i=0; i= MAX_EQUIVALENCE) { - printf("too many chars match?? size=%d c=0x%04x\n", - size, c); + printf("too many chars match?? size=%ld c=0x%04x\n", + (unsigned long)size, c); cli_close(cli, fnum); return False; } diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index cd917f67cd..96e52964b4 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -2080,8 +2080,8 @@ enum { if ((challenge_len = strhex_to_str(challenge, strlen(hex_challenge), hex_challenge)) != 8) { - x_fprintf(x_stderr, "hex decode of %s failed (only got %u bytes)!\n", - hex_challenge, challenge_len); + x_fprintf(x_stderr, "hex decode of %s failed (only got %lu bytes)!\n", + hex_challenge, (unsigned long)challenge_len); exit(1); } opt_challenge = data_blob(challenge, challenge_len); diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 190627e2a5..eae1f97b58 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -203,7 +203,8 @@ static void profilelevel_cb(int msg_type, pid_t pid, void *buf, size_t len) num_replies++; if (len != sizeof(int)) { - fprintf(stderr, "invalid message length %d returned\n", len); + fprintf(stderr, "invalid message length %ld returned\n", + (unsigned long)len); return; } diff --git a/source3/utils/smbfilter.c b/source3/utils/smbfilter.c index 1a0d639f02..5d67c8fc7c 100644 --- a/source3/utils/smbfilter.c +++ b/source3/utils/smbfilter.c @@ -47,7 +47,7 @@ static void save_file(const char *fname, void *packet, size_t length) return; } close(fd); - printf("Wrote %d bytes to %s\n", length, fname); + printf("Wrote %ld bytes to %s\n", (unsigned long)length, fname); } static void filter_reply(char *buf) -- cgit From 827c68deb89b5bd14324c57db14274b36a0790d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Jan 2004 01:21:59 +0000 Subject: Patch based on work from James Peach to convert over to using pread/pwrite. Modified a little to ensure fsp->pos is correct. Fix for #889. Jeremy. (This used to be commit 3a24dc868d95c9bcc2ac3a0dbd50e6e226ac0841) --- examples/VFS/skel_opaque.c | 12 ++ examples/VFS/skel_transparent.c | 10 ++ source3/include/smbprofile.h | 8 +- source3/include/vfs.h | 9 +- source3/include/vfs_macros.h | 6 + source3/lib/system.c | 41 +++++ source3/smbd/fileio.c | 23 +-- source3/smbd/vfs-wrap.c | 320 +++++++++++++++++++++++++--------------- source3/smbd/vfs.c | 43 ++++++ source3/utils/status.c | 6 + 10 files changed, 345 insertions(+), 133 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index de82801d85..310d305cee 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -111,11 +111,21 @@ static ssize_t skel_read(vfs_handle_struct *handle, files_struct *fsp, int fd, v return vfswrap_read(NULL, fsp, fd, data, n); } +static ssize_t skel_pread(vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset) +{ + return vfswrap_pread(NULL, fsp, fd, data, n, offset); +} + static ssize_t skel_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n) { return vfswrap_write(NULL, fsp, fd, data, n); } +ssize_t skel_pwrite(vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset) +{ + return vfswrap_pwrite(NULL, fsp, fd, data, n, offset); +} + static SMB_OFF_T skel_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence) { return vfswrap_lseek(NULL, fsp, filedes, offset, whence); @@ -488,7 +498,9 @@ static vfs_op_tuple skel_op_tuples[] = { {SMB_VFS_OP(skel_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(skel_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(skel_read), SMB_VFS_OP_READ, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_pread), SMB_VFS_OP_PREAD, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(skel_write), SMB_VFS_OP_WRITE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(skel_pwrite), SMB_VFS_OP_PWRITE, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(skel_lseek), SMB_VFS_OP_LSEEK, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(skel_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(skel_fsync), SMB_VFS_OP_FSYNC, SMB_VFS_LAYER_OPAQUE}, diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 7a326741c5..448390e72f 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -110,11 +110,21 @@ static ssize_t skel_read(vfs_handle_struct *handle, files_struct *fsp, int fd, v return SMB_VFS_NEXT_READ(handle, fsp, fd, data, n); } +static ssize_t skel_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset) +{ + return SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, n, offset); +} + static ssize_t skel_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n) { return SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, n); } +static ssize_t skel_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset) +{ + return SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, n, offset); +} + static SMB_OFF_T skel_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence) { return SMB_VFS_NEXT_LSEEK(handle, fsp, filedes, offset, whence); diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index a64c2ce69e..c29a630fe5 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -34,7 +34,7 @@ enum flush_reason_enum { SEEK_FLUSH, READ_FLUSH, WRITE_FLUSH, READRAW_FLUSH, #define PROF_SHMEM_KEY ((key_t)0x07021999) #define PROF_SHM_MAGIC 0x6349985 -#define PROF_SHM_VERSION 7 +#define PROF_SHM_VERSION 8 /* time values in the following structure are in microseconds */ @@ -60,9 +60,15 @@ struct profile_stats { unsigned syscall_read_count; unsigned syscall_read_time; unsigned syscall_read_bytes; /* bytes read with read syscall */ + unsigned syscall_pread_count; + unsigned syscall_pread_time; + unsigned syscall_pread_bytes; /* bytes read with pread syscall */ unsigned syscall_write_count; unsigned syscall_write_time; unsigned syscall_write_bytes; /* bytes written with write syscall */ + unsigned syscall_pwrite_count; + unsigned syscall_pwrite_time; + unsigned syscall_pwrite_bytes; /* bytes written with pwrite syscall */ unsigned syscall_lseek_count; unsigned syscall_lseek_time; unsigned syscall_sendfile_count; diff --git a/source3/include/vfs.h b/source3/include/vfs.h index dd489702aa..8caf64fd99 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -51,7 +51,8 @@ /* Changed to version 7 to include the get_nt_acl info parameter. JRA. */ /* Changed to version 8 includes EA calls. JRA. */ /* Changed to version 9 to include the get_shadow_data call. --metze */ -#define SMB_VFS_INTERFACE_VERSION 9 +/* Changed to version 10 to include pread/pwrite calls. */ +#define SMB_VFS_INTERFACE_VERSION 10 /* to bug old modules witch are trying to compile with the old functions */ @@ -107,7 +108,9 @@ typedef enum _vfs_op_type { SMB_VFS_OP_OPEN, SMB_VFS_OP_CLOSE, SMB_VFS_OP_READ, + SMB_VFS_OP_PREAD, SMB_VFS_OP_WRITE, + SMB_VFS_OP_PWRITE, SMB_VFS_OP_LSEEK, SMB_VFS_OP_SENDFILE, SMB_VFS_OP_RENAME, @@ -213,7 +216,9 @@ struct vfs_ops { int (*open)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, int flags, mode_t mode); int (*close)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd); ssize_t (*read)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n); + ssize_t (*pread)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset); ssize_t (*write)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n); + ssize_t (*pwrite)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset); SMB_OFF_T (*lseek)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset, int whence); ssize_t (*sendfile)(struct vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count); int (*rename)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *old, const char *new); @@ -311,7 +316,9 @@ struct vfs_ops { struct vfs_handle_struct *open; struct vfs_handle_struct *close; struct vfs_handle_struct *read; + struct vfs_handle_struct *pread; struct vfs_handle_struct *write; + struct vfs_handle_struct *pwrite; struct vfs_handle_struct *lseek; struct vfs_handle_struct *sendfile; struct vfs_handle_struct *rename; diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index c4f63c352e..1ec1c5a778 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -46,7 +46,9 @@ #define SMB_VFS_OPEN(conn, fname, flags, mode) ((conn)->vfs.ops.open((conn)->vfs.handles.open, (conn), (fname), (flags), (mode))) #define SMB_VFS_CLOSE(fsp, fd) ((fsp)->conn->vfs.ops.close((fsp)->conn->vfs.handles.close, (fsp), (fd))) #define SMB_VFS_READ(fsp, fd, data, n) ((fsp)->conn->vfs.ops.read((fsp)->conn->vfs.handles.read, (fsp), (fd), (data), (n))) +#define SMB_VFS_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pread((fsp)->conn->vfs.handles.pread, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_WRITE(fsp, fd, data, n) ((fsp)->conn->vfs.ops.write((fsp)->conn->vfs.handles.write, (fsp), (fd), (data), (n))) +#define SMB_VFS_PWRITE(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pwrite((fsp)->conn->vfs.handles.pwrite, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_LSEEK(fsp, fd, offset, whence) ((fsp)->conn->vfs.ops.lseek((fsp)->conn->vfs.handles.lseek, (fsp), (fd), (offset), (whence))) #define SMB_VFS_SENDFILE(tofd, fsp, fromfd, header, offset, count) ((fsp)->conn->vfs.ops.sendfile((fsp)->conn->vfs.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count))) #define SMB_VFS_RENAME(conn, old, new) ((conn)->vfs.ops.rename((conn)->vfs.handles.rename, (conn), (old), (new))) @@ -142,7 +144,9 @@ #define SMB_VFS_OPAQUE_OPEN(conn, fname, flags, mode) ((conn)->vfs_opaque.ops.open((conn)->vfs_opaque.handles.open, (conn), (fname), (flags), (mode))) #define SMB_VFS_OPAQUE_CLOSE(fsp, fd) ((fsp)->conn->vfs_opaque.ops.close((fsp)->conn->vfs_opaque.handles.close, (fsp), (fd))) #define SMB_VFS_OPAQUE_READ(fsp, fd, data, n) ((fsp)->conn->vfs_opaque.ops.read((fsp)->conn->vfs_opaque.handles.read, (fsp), (fd), (data), (n))) +#define SMB_VFS_OPAQUE_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pread((fsp)->conn->vfs_opaque.handles.pread, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_OPAQUE_WRITE(fsp, fd, data, n) ((fsp)->conn->vfs_opaque.ops.write((fsp)->conn->vfs_opaque.handles.write, (fsp), (fd), (data), (n))) +#define SMB_VFS_OPAQUE_PWRITE(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pwrite((fsp)->conn->vfs_opaque.handles.pwrite, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_OPAQUE_LSEEK(fsp, fd, offset, whence) ((fsp)->conn->vfs_opaque.ops.lseek((fsp)->conn->vfs_opaque.handles.lseek, (fsp), (fd), (offset), (whence))) #define SMB_VFS_OPAQUE_SENDFILE(tofd, fsp, fromfd, header, offset, count) ((fsp)->conn->vfs_opaque.ops.sendfile((fsp)->conn->vfs_opaque.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count))) #define SMB_VFS_OPAQUE_RENAME(conn, old, new) ((conn)->vfs_opaque.ops.rename((conn)->vfs_opaque.handles.rename, (conn), (old), (new))) @@ -238,7 +242,9 @@ #define SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode) ((handle)->vfs_next.ops.open((handle)->vfs_next.handles.open, (conn), (fname), (flags), (mode))) #define SMB_VFS_NEXT_CLOSE(handle, fsp, fd) ((handle)->vfs_next.ops.close((handle)->vfs_next.handles.close, (fsp), (fd))) #define SMB_VFS_NEXT_READ(handle, fsp, fd, data, n) ((handle)->vfs_next.ops.read((handle)->vfs_next.handles.read, (fsp), (fd), (data), (n))) +#define SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pread((handle)->vfs_next.handles.pread, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, n) ((handle)->vfs_next.ops.write((handle)->vfs_next.handles.write, (fsp), (fd), (data), (n))) +#define SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pwrite((handle)->vfs_next.handles.pwrite, (fsp), (fd), (data), (n), (off))) #define SMB_VFS_NEXT_LSEEK(handle, fsp, fd, offset, whence) ((handle)->vfs_next.ops.lseek((handle)->vfs_next.handles.lseek, (fsp), (fd), (offset), (whence))) #define SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, fromfd, header, offset, count) ((handle)->vfs_next.ops.sendfile((handle)->vfs_next.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count))) #define SMB_VFS_NEXT_RENAME(handle, conn, old, new) ((handle)->vfs_next.ops.rename((handle)->vfs_next.handles.rename, (conn), (old), (new))) diff --git a/source3/lib/system.c b/source3/lib/system.c index 577f0b9a20..16384c8bdf 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -100,6 +100,47 @@ ssize_t sys_write(int fd, const void *buf, size_t count) return ret; } + +/******************************************************************* +A pread wrapper that will deal with EINTR and 64-bit file offsets. +********************************************************************/ + +#if defined(HAVE_PREAD) || defined(HAVE_PREAD64) +ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off) +{ + ssize_t ret; + + do { +#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64) + ret = pread64(fd, buf, count, off); +#else + ret = pread(fd, buf, count, off); +#endif + } while (ret == -1 && errno == EINTR); + return ret; +} +#endif + +/******************************************************************* +A write wrapper that will deal with EINTR and 64-bit file offsets. +********************************************************************/ + +#if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64) +ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off) +{ + ssize_t ret; + + do { +#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64) + ret = pwrite64(fd, buf, count, off); +#else + ret = pwrite(fd, buf, count, off); +#endif + } while (ret == -1 && errno == EINTR); + return ret; +} +#endif + /******************************************************************* A send wrapper that will deal with EINTR. ********************************************************************/ diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 84339c3a6f..f395954d05 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -95,16 +95,14 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) flush_write_cache(fsp, READ_FLUSH); - if (seek_file(fsp,pos) == -1) { - DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos)); - return(ret); - } - + fsp->pos = pos; + if (n > 0) { #ifdef DMF_FIX int numretries = 3; tryagain: - readret = SMB_VFS_READ(fsp,fsp->fd,data,n); + readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos); + if (readret == -1) { if ((errno == EAGAIN) && numretries) { DEBUG(3,("read_file EAGAIN retry in 10 seconds\n")); @@ -115,7 +113,8 @@ tryagain: return -1; } #else /* NO DMF fix. */ - readret = SMB_VFS_READ(fsp,fsp->fd,data,n); + readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos); + if (readret == -1) return -1; #endif @@ -143,10 +142,12 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_ { ssize_t ret; - if ((pos != -1) && (seek_file(fsp,pos) == -1)) - return -1; - - ret = vfs_write_data(fsp,data,n); + if (pos == -1) + ret = vfs_write_data(fsp, data, n); + else { + fsp->pos = pos; + ret = vfs_pwrite_data(fsp, data, n, pos); + } DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n", fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c index 378a0a1e53..4f2d82734f 100644 --- a/source3/smbd/vfs-wrap.c +++ b/source3/smbd/vfs-wrap.c @@ -44,10 +44,10 @@ void vfswrap_dummy_disconnect(vfs_handle_struct *handle, connection_struct *conn SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { - SMB_BIG_UINT result; + SMB_BIG_UINT result; - result = sys_disk_free(path, small_query, bsize, dfree, dsize); - return result; + result = sys_disk_free(path, small_query, bsize, dfree, dsize); + return result; } int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) @@ -90,22 +90,22 @@ int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_ DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) { - DIR *result; + DIR *result; - START_PROFILE(syscall_opendir); - result = opendir(fname); - END_PROFILE(syscall_opendir); - return result; + START_PROFILE(syscall_opendir); + result = opendir(fname); + END_PROFILE(syscall_opendir); + return result; } struct dirent *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) { - struct dirent *result; + struct dirent *result; - START_PROFILE(syscall_readdir); - result = readdir(dirp); - END_PROFILE(syscall_readdir); - return result; + START_PROFILE(syscall_readdir); + result = readdir(dirp); + END_PROFILE(syscall_readdir); + return result; } int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) @@ -133,71 +133,154 @@ int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char errno = saved_errno; } - END_PROFILE(syscall_mkdir); - return result; + END_PROFILE(syscall_mkdir); + return result; } int vfswrap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result; + int result; - START_PROFILE(syscall_rmdir); - result = rmdir(path); - END_PROFILE(syscall_rmdir); - return result; + START_PROFILE(syscall_rmdir); + result = rmdir(path); + END_PROFILE(syscall_rmdir); + return result; } int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp) { - int result; + int result; - START_PROFILE(syscall_closedir); - result = closedir(dirp); - END_PROFILE(syscall_closedir); - return result; + START_PROFILE(syscall_closedir); + result = closedir(dirp); + END_PROFILE(syscall_closedir); + return result; } /* File operations */ int vfswrap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode) { - int result; + int result; - START_PROFILE(syscall_open); - result = sys_open(fname, flags, mode); - END_PROFILE(syscall_open); - return result; + START_PROFILE(syscall_open); + result = sys_open(fname, flags, mode); + END_PROFILE(syscall_open); + return result; } int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd) { - int result; + int result; - START_PROFILE(syscall_close); + START_PROFILE(syscall_close); - result = close(fd); - END_PROFILE(syscall_close); - return result; + result = close(fd); + END_PROFILE(syscall_close); + return result; } ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n) { - ssize_t result; + ssize_t result; - START_PROFILE_BYTES(syscall_read, n); - result = sys_read(fd, data, n); - END_PROFILE(syscall_read); - return result; + START_PROFILE_BYTES(syscall_read, n); + result = sys_read(fd, data, n); + END_PROFILE(syscall_read); + return result; +} + +ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, + size_t n, SMB_OFF_T offset) +{ + ssize_t result; + +#if defined(HAVE_PREAD) || defined(HAVE_PREAD64) + START_PROFILE_BYTES(syscall_pread, n); + result = sys_pread(fd, data, n, offset); + END_PROFILE(syscall_pread); + + if (result == -1 && errno == ESPIPE) { + /* Maintain the fiction that pipes can be seeked (sought?) on. */ + result = SMB_VFS_READ(fsp, fd, data, n); + fsp->pos = 0; + } + +#else /* HAVE_PREAD */ + SMB_OFF_T curr; + int lerrno; + + curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); + if (curr == -1 && errno == ESPIPE) { + /* Maintain the fiction that pipes can be seeked (sought?) on. */ + result = SMB_VFS_READ(fsp, fd, data, n); + fsp->pos = 0; + return result; + } + + if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) { + return -1; + } + + errno = 0; + result = SMB_VFS_READ(fsp, fd, data, n); + lerrno = errno; + + SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET); + errno = lerrno; + +#endif /* HAVE_PREAD */ + + return result; } ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n) { - ssize_t result; + ssize_t result; + + START_PROFILE_BYTES(syscall_write, n); + result = sys_write(fd, data, n); + END_PROFILE(syscall_write); + return result; +} + +ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, + size_t n, SMB_OFF_T offset) +{ + ssize_t result; + +#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64) + START_PROFILE_BYTES(syscall_pwrite, n); + result = sys_pwrite(fd, data, n, offset); + END_PROFILE(syscall_pwrite); + + if (result == -1 && errno == ESPIPE) { + /* Maintain the fiction that pipes can be sought on. */ + result = SMB_VFS_WRITE(fsp, fd, data, n); + } + +#else /* HAVE_PWRITE */ + SMB_OFF_T curr; + int lerrno; - START_PROFILE_BYTES(syscall_write, n); - result = sys_write(fd, data, n); - END_PROFILE(syscall_write); - return result; + curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR); + if (curr == -1) { + return -1; + } + + if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) { + return -1; + } + + result = SMB_VFS_WRITE(fsp, fd, data, n); + lerrno = errno; + + SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET); + errno = lerrno; + +#endif /* HAVE_PWRITE */ + + return result; } SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence) @@ -340,13 +423,12 @@ int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const cha int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd) { #ifdef HAVE_FSYNC - int result; - - START_PROFILE(syscall_fsync); + int result; - result = fsync(fd); - END_PROFILE(syscall_fsync); - return result; + START_PROFILE(syscall_fsync); + result = fsync(fd); + END_PROFILE(syscall_fsync); + return result; #else return 0; #endif @@ -354,49 +436,49 @@ int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd) int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf) { - int result; + int result; - START_PROFILE(syscall_stat); - result = sys_stat(fname, sbuf); - END_PROFILE(syscall_stat); - return result; + START_PROFILE(syscall_stat); + result = sys_stat(fname, sbuf); + END_PROFILE(syscall_stat); + return result; } int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf) { - int result; + int result; - START_PROFILE(syscall_fstat); - result = sys_fstat(fd, sbuf); - END_PROFILE(syscall_fstat); - return result; + START_PROFILE(syscall_fstat); + result = sys_fstat(fd, sbuf); + END_PROFILE(syscall_fstat); + return result; } int vfswrap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) { - int result; + int result; - START_PROFILE(syscall_lstat); - result = sys_lstat(path, sbuf); - END_PROFILE(syscall_lstat); - return result; + START_PROFILE(syscall_lstat); + result = sys_lstat(path, sbuf); + END_PROFILE(syscall_lstat); + return result; } int vfswrap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result; + int result; - START_PROFILE(syscall_unlink); - result = unlink(path); - END_PROFILE(syscall_unlink); - return result; + START_PROFILE(syscall_unlink); + result = unlink(path); + END_PROFILE(syscall_unlink); + return result; } int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode) { - int result; + int result; - START_PROFILE(syscall_chmod); + START_PROFILE(syscall_chmod); /* * We need to do this due to the fact that the default POSIX ACL @@ -415,9 +497,9 @@ int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char errno = saved_errno; } - result = chmod(path, mode); - END_PROFILE(syscall_chmod); - return result; + result = chmod(path, mode); + END_PROFILE(syscall_chmod); + return result; } int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) @@ -455,58 +537,57 @@ int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t int vfswrap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid) { - int result; + int result; - START_PROFILE(syscall_chown); - result = sys_chown(path, uid, gid); - END_PROFILE(syscall_chown); - return result; + START_PROFILE(syscall_chown); + result = sys_chown(path, uid, gid); + END_PROFILE(syscall_chown); + return result; } int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid) { #ifdef HAVE_FCHOWN - int result; - - START_PROFILE(syscall_fchown); + int result; - result = fchown(fd, uid, gid); - END_PROFILE(syscall_fchown); - return result; + START_PROFILE(syscall_fchown); + result = fchown(fd, uid, gid); + END_PROFILE(syscall_fchown); + return result; #else - errno = ENOSYS; - return -1; + errno = ENOSYS; + return -1; #endif } int vfswrap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path) { - int result; + int result; - START_PROFILE(syscall_chdir); - result = chdir(path); - END_PROFILE(syscall_chdir); - return result; + START_PROFILE(syscall_chdir); + result = chdir(path); + END_PROFILE(syscall_chdir); + return result; } char *vfswrap_getwd(vfs_handle_struct *handle, connection_struct *conn, char *path) { - char *result; + char *result; - START_PROFILE(syscall_getwd); - result = sys_getwd(path); - END_PROFILE(syscall_getwd); - return result; + START_PROFILE(syscall_getwd); + result = sys_getwd(path); + END_PROFILE(syscall_getwd); + return result; } int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times) { - int result; + int result; - START_PROFILE(syscall_utime); - result = utime(path, times); - END_PROFILE(syscall_utime); - return result; + START_PROFILE(syscall_utime); + result = utime(path, times); + END_PROFILE(syscall_utime); + return result; } /********************************************************************* @@ -643,33 +724,32 @@ int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) { - BOOL result; - - START_PROFILE(syscall_fcntl_lock); + BOOL result; - result = fcntl_lock(fd, op, offset, count,type); - END_PROFILE(syscall_fcntl_lock); - return result; + START_PROFILE(syscall_fcntl_lock); + result = fcntl_lock(fd, op, offset, count,type); + END_PROFILE(syscall_fcntl_lock); + return result; } int vfswrap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) { - int result; + int result; - START_PROFILE(syscall_symlink); - result = sys_symlink(oldpath, newpath); - END_PROFILE(syscall_symlink); - return result; + START_PROFILE(syscall_symlink); + result = sys_symlink(oldpath, newpath); + END_PROFILE(syscall_symlink); + return result; } int vfswrap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz) { - int result; + int result; - START_PROFILE(syscall_readlink); - result = sys_readlink(path, buf, bufsiz); - END_PROFILE(syscall_readlink); - return result; + START_PROFILE(syscall_readlink); + result = sys_readlink(path, buf, bufsiz); + END_PROFILE(syscall_readlink); + return result; } int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath) diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 753db4cece..2f981c743f 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -71,7 +71,9 @@ static struct vfs_ops default_vfs = { vfswrap_open, vfswrap_close, vfswrap_read, + vfswrap_pread, vfswrap_write, + vfswrap_pwrite, vfswrap_lseek, vfswrap_sendfile, vfswrap_rename, @@ -429,6 +431,28 @@ ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count) return (ssize_t)total; } +ssize_t vfs_pread_data(files_struct *fsp, char *buf, + size_t byte_count, SMB_OFF_T offset) +{ + size_t total=0; + + while (total < byte_count) + { + ssize_t ret = SMB_VFS_PREAD(fsp, fsp->fd, buf + total, + byte_count - total, offset + total); + + if (ret == 0) return total; + if (ret == -1) { + if (errno == EINTR) + continue; + else + return -1; + } + total += ret; + } + return (ssize_t)total; +} + /**************************************************************************** Write data to a fd on the vfs. ****************************************************************************/ @@ -451,6 +475,25 @@ ssize_t vfs_write_data(files_struct *fsp,const char *buffer,size_t N) return (ssize_t)total; } +ssize_t vfs_pwrite_data(files_struct *fsp,const char *buffer, + size_t N, SMB_OFF_T offset) +{ + size_t total=0; + ssize_t ret; + + while (total < N) { + ret = SMB_VFS_PWRITE(fsp, fsp->fd, buffer + total, + N - total, offset + total); + + if (ret == -1) + return -1; + if (ret == 0) + return total; + + total += ret; + } + return (ssize_t)total; +} /**************************************************************************** An allocate file space call using the vfs interface. Allocates space for a file from a filedescriptor. diff --git a/source3/utils/status.c b/source3/utils/status.c index 54dce1ecf0..4585b101b2 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -197,6 +197,12 @@ static int profile_dump(void) d_printf("write_count: %u\n", profile_p->syscall_write_count); d_printf("write_time: %u\n", profile_p->syscall_write_time); d_printf("write_bytes: %u\n", profile_p->syscall_write_bytes); + d_printf("pread_count: %u\n", profile_p->syscall_pread_count); + d_printf("pread_time: %u\n", profile_p->syscall_pread_time); + d_printf("pread_bytes: %u\n", profile_p->syscall_pread_bytes); + d_printf("pwrite_count: %u\n", profile_p->syscall_pwrite_count); + d_printf("pwrite_time: %u\n", profile_p->syscall_pwrite_time); + d_printf("pwrite_bytes: %u\n", profile_p->syscall_pwrite_bytes); #ifdef WITH_SENDFILE d_printf("sendfile_count: %u\n", profile_p->syscall_sendfile_count); d_printf("sendfile_time: %u\n", profile_p->syscall_sendfile_time); -- cgit From 6d7eb1adf32b223a771237bf063517974f632036 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 01:59:20 +0000 Subject: Merge winbind from Samba 3.0 onto HEAD. Changes include: - header changes for better pre-compiled headers (tridge) - get a list of sids for a given user (tridge) - fix function prototype and a few other minor things Andrew Bartlett (This used to be commit 60107efdc61247034424d008c6f1eb4d46a19881) --- source3/nsswitch/wbinfo.c | 44 ++++++++++- source3/nsswitch/winbind_nss_linux.c | 149 +++++++++++++++++++++++++++++++++++ source3/nsswitch/winbindd.c | 3 + source3/nsswitch/winbindd.h | 1 - source3/nsswitch/winbindd_acct.c | 1 + source3/nsswitch/winbindd_ads.c | 3 +- source3/nsswitch/winbindd_cache.c | 1 + source3/nsswitch/winbindd_cm.c | 3 +- source3/nsswitch/winbindd_dual.c | 1 + source3/nsswitch/winbindd_group.c | 86 ++++++++++++++++++++ source3/nsswitch/winbindd_misc.c | 1 + source3/nsswitch/winbindd_nss.h | 3 + source3/nsswitch/winbindd_pam.c | 1 + source3/nsswitch/winbindd_rpc.c | 1 + source3/nsswitch/winbindd_sid.c | 20 +++-- source3/nsswitch/winbindd_user.c | 1 + source3/nsswitch/winbindd_util.c | 3 +- source3/nsswitch/winbindd_wins.c | 1 + 18 files changed, 309 insertions(+), 14 deletions(-) diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 55eeb9fa39..792af84827 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -136,6 +136,37 @@ static BOOL wbinfo_get_usergroups(char *user) return True; } + +/* List group SIDs a user SID is a member of */ +static BOOL wbinfo_get_usersids(char *user_sid) +{ + struct winbindd_request request; + struct winbindd_response response; + NSS_STATUS result; + int i; + const char *s; + + ZERO_STRUCT(response); + + /* Send request */ + fstrcpy(request.data.sid, user_sid); + + result = winbindd_request(WINBINDD_GETUSERSIDS, &request, &response); + + if (result != NSS_STATUS_SUCCESS) + return False; + + s = response.extra_data; + for (i = 0; i < response.data.num_entries; i++) { + d_printf("%s\n", s); + s += strlen(s) + 1; + } + + SAFE_FREE(response.extra_data); + + return True; +} + /* Convert NetBIOS name to IP */ static BOOL wbinfo_wins_byname(char *name) @@ -920,7 +951,8 @@ enum { OPT_SET_AUTH_USER = 1000, OPT_GET_AUTH_USER, OPT_DOMAIN_NAME, - OPT_SEQUENCE + OPT_SEQUENCE, + OPT_USERSIDS }; int main(int argc, char **argv) @@ -961,11 +993,12 @@ int main(int argc, char **argv) { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', "Show all most info we have about the domain" }, { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" }, + { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" }, { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" }, { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" }, { "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL }, { "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" }, - { "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operatio", "domain" }, + { "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operation", "domain" }, POPT_COMMON_VERSION POPT_TABLEEND }; @@ -1099,6 +1132,13 @@ int main(int argc, char **argv) goto done; } break; + case OPT_USERSIDS: + if (!wbinfo_get_usersids(string_arg)) { + d_printf("Could not get group SIDs for user SID %s\n", + string_arg); + goto done; + } + break; case 'a': { BOOL got_error = False; diff --git a/source3/nsswitch/winbind_nss_linux.c b/source3/nsswitch/winbind_nss_linux.c index 125bc8ccda..ac4a861ff1 100644 --- a/source3/nsswitch/winbind_nss_linux.c +++ b/source3/nsswitch/winbind_nss_linux.c @@ -860,3 +860,152 @@ _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start, done: return ret; } + + +/* return a list of group SIDs for a user SID */ +NSS_STATUS +_nss_winbind_getusersids(const char *user_sid, char **group_sids, + int *num_groups, + char *buffer, size_t buf_size, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_request request; + struct winbindd_response response; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: getusersids %s\n", getpid(), user_sid); +#endif + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + strncpy(request.data.sid, user_sid,sizeof(request.data.sid) - 1); + request.data.sid[sizeof(request.data.sid) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_GETUSERSIDS, &request, &response); + + if (ret != NSS_STATUS_SUCCESS) { + goto done; + } + + if (buf_size < response.length - sizeof(response)) { + ret = NSS_STATUS_TRYAGAIN; + errno = *errnop = ERANGE; + goto done; + } + + *num_groups = response.data.num_entries; + *group_sids = buffer; + memcpy(buffer, response.extra_data, response.length - sizeof(response)); + errno = *errnop = 0; + + done: + free_response(&response); + return ret; +} + + +/* map a user or group name to a SID string */ +NSS_STATUS +_nss_winbind_nametosid(const char *name, char **sid, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_response response; + struct winbindd_request request; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: nametosid %s\n", getpid(), name); +#endif + + ZERO_STRUCT(response); + ZERO_STRUCT(request); + + strncpy(request.data.name.name, name, + sizeof(request.data.name.name) - 1); + request.data.name.name[sizeof(request.data.name.name) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_LOOKUPNAME, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + if (buflen < strlen(response.data.sid.sid)+1) { + ret = NSS_STATUS_TRYAGAIN; + *errnop = errno = ERANGE; + goto failed; + } + + *errnop = errno = 0; + *sid = buffer; + strcpy(*sid, response.data.sid.sid); + +failed: + free_response(&response); + return ret; +} + +/* map a sid string to a user or group name */ +NSS_STATUS +_nss_winbind_sidtoname(const char *sid, char **name, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_response response; + struct winbindd_request request; + static char sep_char; + unsigned needed; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: sidtoname %s\n", getpid(), sid); +#endif + + /* we need to fetch the separator first time through */ + if (!sep_char) { + ZERO_STRUCT(response); + ZERO_STRUCT(request); + + ret = winbindd_request(WINBINDD_INFO, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + sep_char = response.data.info.winbind_separator; + free_response(&response); + } + + + strncpy(request.data.sid, sid, + sizeof(request.data.sid) - 1); + request.data.sid[sizeof(request.data.sid) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_LOOKUPSID, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + needed = + strlen(response.data.name.dom_name) + + strlen(response.data.name.name) + 2; + + if (buflen < needed) { + ret = NSS_STATUS_TRYAGAIN; + *errnop = errno = ERANGE; + goto failed; + } + + snprintf(buffer, needed, "%s%c%s", + response.data.name.dom_name, + sep_char, + response.data.name.name); + + *name = buffer; + *errnop = errno = 0; + +failed: + free_response(&response); + return ret; +} diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index b1c0c67d52..8ce528d2b0 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" BOOL opt_nocache = False; @@ -220,6 +221,7 @@ static struct dispatch_table dispatch_table[] = { { WINBINDD_GETPWENT, winbindd_getpwent, "GETPWENT" }, { WINBINDD_GETGROUPS, winbindd_getgroups, "GETGROUPS" }, + { WINBINDD_GETUSERSIDS, winbindd_getusersids, "GETUSERSIDS" }, /* Group functions */ @@ -722,6 +724,7 @@ static void process_loop(void) && *(uint32 *) &state->request != sizeof(state->request)) { DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %ld\n", (unsigned long)state->request.pid, *(uint32 *) &state->request, (unsigned long)sizeof(state->request))); + DEBUGADD(0, ("This usually means that you are running old wbinfo, pam_winbind or libnss_winbind clients\n")); remove_client(state); break; diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 7c612ea61b..5dbe422bc1 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -25,7 +25,6 @@ #ifndef _WINBINDD_H #define _WINBINDD_H -#include "includes.h" #include "nterr.h" #include "winbindd_nss.h" diff --git a/source3/nsswitch/winbindd_acct.c b/source3/nsswitch/winbindd_acct.c index 0c06df7fdd..08b9e2172c 100644 --- a/source3/nsswitch/winbindd_acct.c +++ b/source3/nsswitch/winbindd_acct.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index f8582aee99..90b83bccd0 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #ifdef HAVE_ADS @@ -553,8 +554,6 @@ static NTSTATUS lookup_usergroups_alt(struct winbindd_domain *domain, done: if (res) ads_msgfree(ads, res); - if (msg) - ads_msgfree(ads, msg); return status; } diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index 91ef38a368..a3c1706b75 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index c255d21102..2b561be31d 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -56,6 +56,7 @@ */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS @@ -183,8 +184,6 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i machine_password, lp_workgroup()))) { DEBUG(4,("failed kerberos session setup with %s\n", nt_errstr(result))); - if (NT_STATUS_IS_OK(result)) - result = NT_STATUS_UNSUCCESSFUL; } } new_conn->cli->use_kerberos = False; diff --git a/source3/nsswitch/winbindd_dual.c b/source3/nsswitch/winbindd_dual.c index 167630b0e1..a9796afa36 100644 --- a/source3/nsswitch/winbindd_dual.c +++ b/source3/nsswitch/winbindd_dual.c @@ -29,6 +29,7 @@ */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 1c5d6acf51..180a3db8e2 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS @@ -1081,3 +1082,88 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) return result; } + + +/* Get user supplementary sids. This is equivalent to the + winbindd_getgroups() function but it involves a SID->SIDs mapping + rather than a NAME->SID->SIDS->GIDS mapping, which means we avoid + idmap. This call is designed to be used with applications that need + to do ACL evaluation themselves. Note that the cached info3 data is + not used + + this function assumes that the SID that comes in is a user SID. If + you pass in another type of SID then you may get unpredictable + results. +*/ +enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state) +{ + DOM_SID user_sid; + NTSTATUS status; + DOM_SID **user_grpsids; + struct winbindd_domain *domain; + enum winbindd_result result = WINBINDD_ERROR; + unsigned int i; + TALLOC_CTX *mem_ctx; + char *ret; + uint32 num_groups; + unsigned ofs, ret_size = 0; + + /* Ensure null termination */ + state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; + + if (!string_to_sid(&user_sid, state->request.data.sid)) { + DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid)); + return WINBINDD_ERROR; + } + + if (!(mem_ctx = talloc_init("winbindd_getusersids(%s)", + state->request.data.username))) { + return WINBINDD_ERROR; + } + + /* Get info for the domain */ + if ((domain = find_domain_from_sid(&user_sid)) == NULL) { + DEBUG(0,("could not find domain entry for sid %s\n", + sid_string_static(&user_sid))); + goto done; + } + + status = domain->methods->lookup_usergroups(domain, mem_ctx, + &user_sid, &num_groups, + &user_grpsids); + if (!NT_STATUS_IS_OK(status)) + goto done; + + if (num_groups == 0) { + goto no_groups; + } + + /* work out the response size */ + for (i = 0; i < num_groups; i++) { + const char *s = sid_string_static(user_grpsids[i]); + ret_size += strlen(s) + 1; + } + + /* build the reply */ + ret = malloc(ret_size); + if (!ret) goto done; + ofs = 0; + for (i = 0; i < num_groups; i++) { + const char *s = sid_string_static(user_grpsids[i]); + safe_strcpy(ret + ofs, s, ret_size - ofs); + ofs += strlen(ret+ofs) + 1; + } + +no_groups: + /* Send data back to client */ + state->response.data.num_entries = num_groups; + state->response.extra_data = ret; + state->response.length += ret_size; + result = WINBINDD_OK; + + done: + talloc_destroy(mem_ctx); + + return result; +} + diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c index 19beddc304..08b5be827d 100644 --- a/source3/nsswitch/winbindd_misc.c +++ b/source3/nsswitch/winbindd_misc.c @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index 2383db551e..0dd00e9b39 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -121,6 +121,9 @@ enum winbindd_cmd { /* find the location of our privileged pipe */ WINBINDD_PRIV_PIPE_DIR, + /* return a list of group sids for a user sid */ + WINBINDD_GETUSERSIDS, + WINBINDD_NUM_CMDS }; diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index dba2fe8ba4..31698b4798 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 81bbc774d1..f619aa3564 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index 0faeec5636..7c4c8d804a 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS @@ -83,6 +84,7 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) char *name_domain, *name_user; DOM_SID sid; struct winbindd_domain *domain; + char *p; /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.name.dom_name)-1]='\0'; @@ -90,13 +92,19 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0'; - DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid, - state->request.data.name.dom_name, - lp_winbind_separator(), - state->request.data.name.name)); + /* cope with the name being a fully qualified name */ + p = strstr(state->request.data.name.name, lp_winbind_separator()); + if (p) { + *p = 0; + name_domain = state->request.data.name.name; + name_user = p+1; + } else { + name_domain = state->request.data.name.dom_name; + name_user = state->request.data.name.name; + } - name_domain = state->request.data.name.dom_name; - name_user = state->request.data.name.name; + DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid, + name_domain, lp_winbind_separator(), name_user)); if ((domain = find_domain_from_name(name_domain)) == NULL) { DEBUG(0, ("could not find domain entry for domain %s\n", diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index eab88c842e..903a2a8bfa 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 95aaec3b1e..f29ed37650 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS @@ -340,7 +341,7 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid) /* Given a domain sid, return the struct winbindd domain info for it */ -struct winbindd_domain *find_our_domain() +struct winbindd_domain *find_our_domain(void) { struct winbindd_domain *domain; diff --git a/source3/nsswitch/winbindd_wins.c b/source3/nsswitch/winbindd_wins.c index 49bee2dc9f..bc982d0044 100644 --- a/source3/nsswitch/winbindd_wins.c +++ b/source3/nsswitch/winbindd_wins.c @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS -- cgit From 24218aaf36791e1ac85110281dcd56b59499f4ab Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 02:29:29 +0000 Subject: (merge from 3.0) Fixes bug 924 Andrew Bartlett (This used to be commit ee18f897f9452a84a6b11c077ff706beb49441ff) --- testsuite/build_farm/torture-RW2.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/build_farm/torture-RW2.test b/testsuite/build_farm/torture-RW2.test index a647d9de2e..dc457decab 100644 --- a/testsuite/build_farm/torture-RW2.test +++ b/testsuite/build_farm/torture-RW2.test @@ -1,2 +1,2 @@ . torture_setup.fns -test_torture "RW22" +test_torture "RW2" -- cgit From 3c900cf40b3389d59f0715385e49f490081f86ea Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 08:11:19 +0000 Subject: GUID is struct uuid in HEAD. Andrew Bartlett (This used to be commit ec24c7f42ac344d14c0e29d4b49c07d8ce213448) --- source3/include/rpc_ds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/include/rpc_ds.h b/source3/include/rpc_ds.h index 3cb7c64955..e06918730a 100644 --- a/source3/include/rpc_ds.h +++ b/source3/include/rpc_ds.h @@ -124,7 +124,7 @@ struct ds_domain_trust { uint32 parent_index; uint32 trust_type; uint32 trust_attributes; - GUID guid; + struct uuid guid; DOM_SID sid; char *netbios_domain; -- cgit From 7f87b207a72811b0d00945fadafc51559e561828 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 08:12:35 +0000 Subject: Merge NTLMSSP fixes from 3.0 to HEAD. Andrew Bartlett (This used to be commit f7d39c787771616ddb015bd77e3e6cd33f0c7a15) --- source3/include/ntlmssp.h | 8 +++--- source3/libsmb/ntlmssp.c | 59 ++++++++++++++++++++++++++++++------------- source3/libsmb/ntlmssp_sign.c | 57 +++++++++++++++++++++++++++++++---------- source3/libsmb/pwd_cache.c | 10 ++++++-- source3/rpc_client/cli_pipe.c | 17 +++++++++---- 5 files changed, 109 insertions(+), 42 deletions(-) diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h index 681d4071db..24ac796761 100644 --- a/source3/include/ntlmssp.h +++ b/source3/include/ntlmssp.h @@ -147,10 +147,10 @@ typedef struct ntlmssp_state uint32 ntlmssp_seq_num; /* ntlmv2 */ - char send_sign_const[16]; - char send_seal_const[16]; - char recv_sign_const[16]; - char recv_seal_const[16]; + unsigned char send_sign_const[16]; + unsigned char send_seal_const[16]; + unsigned char recv_sign_const[16]; + unsigned char recv_seal_const[16]; unsigned char send_sign_hash[258]; unsigned char send_seal_hash[258]; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 7b821da0fd..40d7f41109 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -338,6 +338,10 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + } + if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } @@ -577,6 +581,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } } + if (auth_flags) + ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth()); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { SAFE_FREE(domain); SAFE_FREE(user); @@ -654,7 +661,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, /* Finally, actually ask if the password is OK */ - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) { + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, + &nt_session_key, &lm_session_key))) { data_blob_free(&encrypted_session_key); return nt_status; } @@ -670,24 +678,28 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, sizeof(session_nonce), session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n")); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); - - }else { - data_blob_free(&encrypted_session_key); + + } else { DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); - return NT_STATUS_INVALID_PARAMETER; + session_key = data_blob(NULL, 0); } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { - if (lm_session_key.data && lm_session_key.length >= 8 && - ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, - session_key.data); - DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); - dump_data_pw("LM session key:\n", session_key.data, session_key.length); + if (lm_session_key.data && lm_session_key.length >= 8) { + if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, + session_key.data); + DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); + dump_data_pw("LM session key:\n", session_key.data, session_key.length); + } else { + /* use the key unmodified - it's + * probably a NULL key from the guest + * login */ + session_key = lm_session_key; + } } else { - data_blob_free(&encrypted_session_key); DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); - return NT_STATUS_INVALID_PARAMETER; + session_key = data_blob(NULL, 0); } } else if (nt_session_key.data) { session_key = nt_session_key; @@ -698,9 +710,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); } else { - data_blob_free(&encrypted_session_key); DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n")); - return NT_STATUS_INVALID_PARAMETER; + session_key = data_blob(NULL, 0); } /* With KEY_EXCH, the client supplies the proposed session key, @@ -714,6 +725,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } else if (!session_key.data || session_key.length != 16) { DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", session_key.length)); + ntlmssp_state->session_key = session_key; } else { dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); SamOEMhash(encrypted_session_key.data, @@ -723,12 +735,18 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, encrypted_session_key.data, encrypted_session_key.length); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, - encrypted_session_key.length); + encrypted_session_key.length); } } else { ntlmssp_state->session_key = session_key; } + if (!NT_STATUS_IS_OK(nt_status)) { + ntlmssp_state->session_key = data_blob(NULL, 0); + } else if (ntlmssp_state->session_key.length) { + nt_status = ntlmssp_sign_init(ntlmssp_state); + } + data_blob_free(&encrypted_session_key); /* allow arbitarily many authentications */ @@ -906,7 +924,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } if (!ntlmssp_state->password) { + static const uchar zeros[16]; /* do nothing - blobs are zero length */ + + /* session key is all zeros */ + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16); + + /* not doing NLTM2 without a password */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } else if (ntlmssp_state->use_ntlmv2) { if (!struct_blob.length) { diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index ea1a7037c9..6ce7a76743 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -53,7 +53,7 @@ static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) hash[257] = index_j; } -static void calc_hash(unsigned char *hash, const char *k2, int k2l) +static void calc_hash(unsigned char hash[258], const char *k2, int k2l) { unsigned char j = 0; int ind; @@ -78,7 +78,7 @@ static void calc_hash(unsigned char *hash, const char *k2, int k2l) hash[257] = 0; } -static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], +static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char digest[16], DATA_BLOB session_key, const char *constant) { @@ -91,8 +91,8 @@ static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], MD5Init(&ctx3); MD5Update(&ctx3, session_key.data, session_key.length); - MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)); - MD5Final((unsigned char *)digest, &ctx3); + MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)+1); + MD5Final(digest, &ctx3); calc_hash(hash, digest, 16); } @@ -109,12 +109,12 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; - char seq_num[4]; + uchar seq_num[4]; uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); - hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); + hmac_md5_update(seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); @@ -122,13 +122,16 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, , ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } - switch (direction) { - case NTLMSSP_SEND: - NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); - break; - case NTLMSSP_RECEIVE: - NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); - break; + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + switch (direction) { + case NTLMSSP_SEND: + NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); + break; + case NTLMSSP_RECEIVE: + NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); + break; + } } } else { uint32 crc; @@ -148,7 +151,13 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, const uchar *data, size_t length, DATA_BLOB *sig) { - NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); + NTSTATUS nt_status; + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot check sign packet\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); /* increment counter on send */ ntlmssp_state->ntlmssp_seq_num++; @@ -168,6 +177,11 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, DATA_BLOB local_sig; NTSTATUS nt_status; + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot check packet signature\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + if (sig->length < 8) { DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n", (unsigned long)sig->length)); @@ -208,6 +222,11 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, uchar *data, size_t length, DATA_BLOB *sig) { + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot seal packet\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + DEBUG(10,("ntlmssp_seal_data: seal\n")); dump_data_pw("ntlmssp clear data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { @@ -270,6 +289,11 @@ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, uchar *data, size_t length, DATA_BLOB *sig) { + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot unseal packet\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + DEBUG(10,("ntlmssp__unseal_data: seal\n")); dump_data_pw("ntlmssp sealed data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { @@ -295,6 +319,11 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot intialise signing\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { const char *send_sign_const; diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index f45832d7d7..7ba6cfc96f 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -45,8 +45,14 @@ static void pwd_make_lm_nt_16(struct pwd_info *pwd, const char *clr) { pwd_init(pwd); - nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); - pwd->null_pwd = False; + if (!clr) { + ZERO_STRUCT(pwd->smb_nt_pwd); + ZERO_STRUCT(pwd->smb_lm_pwd); + pwd->null_pwd = True; + } else { + nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); + pwd->null_pwd = False; + } pwd->crypted = False; } diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 49abf787ee..3213e955b6 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1342,11 +1342,18 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na if (!NT_STATUS_IS_OK(nt_status)) return False; - pwd_get_cleartext(&cli->pwd, password); - nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, - password); - if (!NT_STATUS_IS_OK(nt_status)) - return False; + if (cli->pwd.null_pwd) { + nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, + NULL); + if (!NT_STATUS_IS_OK(nt_status)) + return False; + } else { + pwd_get_cleartext(&cli->pwd, password); + nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, + password); + if (!NT_STATUS_IS_OK(nt_status)) + return False; + } if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; -- cgit From f4a17613110562e3102c10b0cd762ba59bb5c099 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jan 2004 08:25:03 +0000 Subject: merge torture changes from Samba 3.0 -> HEAD (This used to be commit 6e9c68217bec1e4138b5eb9a9ed85807b31bbdb8) --- source3/torture/torture.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 2ffae74016..2e6bc49d55 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -2792,8 +2792,8 @@ static BOOL run_oplock3(int dummy) */ static BOOL run_deletetest(int dummy) { - struct cli_state *cli1; - struct cli_state *cli2; + struct cli_state *cli1 = NULL; + struct cli_state *cli2 = NULL; const char *fname = "\\delete.file"; int fnum1 = -1; int fnum2 = -1; @@ -3201,15 +3201,15 @@ static BOOL run_deletetest(int dummy) * intialized, because these functions don't handle * uninitialized connections. */ - cli_close(cli1, fnum1); - cli_close(cli1, fnum2); + if (fnum1 != -1) cli_close(cli1, fnum1); + if (fnum2 != -1) cli_close(cli1, fnum2); cli_setatr(cli1, fname, 0, 0); cli_unlink(cli1, fname); - if (!torture_close_connection(cli1)) { + if (cli1 && !torture_close_connection(cli1)) { correct = False; } - if (!torture_close_connection(cli2)) { + if (cli2 && !torture_close_connection(cli2)) { correct = False; } return correct; -- cgit From 077d5b2f69f2b32dd6b58c8931909a222401ceaf Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 6 Jan 2004 14:45:56 +0000 Subject: merging from 3.0 (This used to be commit 694052f8a9cc703d4e4ec8075c623ab7122a169b) --- examples/LDAP/smbldap-tools/CONTRIBUTORS | 10 +- examples/LDAP/smbldap-tools/ChangeLog | 105 ++++- examples/LDAP/smbldap-tools/FILES | 2 + examples/LDAP/smbldap-tools/INFRASTRUCTURE | 11 + examples/LDAP/smbldap-tools/INSTALL | 2 + examples/LDAP/smbldap-tools/Makefile | 2 +- examples/LDAP/smbldap-tools/README | 3 + examples/LDAP/smbldap-tools/TODO | 2 + examples/LDAP/smbldap-tools/smbldap-groupadd.pl | 95 +++- examples/LDAP/smbldap-tools/smbldap-groupdel.pl | 13 +- examples/LDAP/smbldap-tools/smbldap-groupmod.pl | 155 +++++-- examples/LDAP/smbldap-tools/smbldap-groupshow.pl | 4 +- .../LDAP/smbldap-tools/smbldap-migrate-accounts.pl | 46 +- .../LDAP/smbldap-tools/smbldap-migrate-groups.pl | 88 ++-- examples/LDAP/smbldap-tools/smbldap-passwd.pl | 117 ++--- examples/LDAP/smbldap-tools/smbldap-populate.pl | 138 ++++-- examples/LDAP/smbldap-tools/smbldap-tools.spec | 70 +-- examples/LDAP/smbldap-tools/smbldap-useradd.pl | 360 ++++++++------- examples/LDAP/smbldap-tools/smbldap-userdel.pl | 32 +- examples/LDAP/smbldap-tools/smbldap-usermod.pl | 270 +++++++----- examples/LDAP/smbldap-tools/smbldap-usershow.pl | 4 +- examples/LDAP/smbldap-tools/smbldap_conf.pm | 63 +-- examples/LDAP/smbldap-tools/smbldap_tools.pm | 482 ++++++++++++--------- 23 files changed, 1253 insertions(+), 821 deletions(-) diff --git a/examples/LDAP/smbldap-tools/CONTRIBUTORS b/examples/LDAP/smbldap-tools/CONTRIBUTORS index 59dafcc89e..d080dd020e 100644 --- a/examples/LDAP/smbldap-tools/CONTRIBUTORS +++ b/examples/LDAP/smbldap-tools/CONTRIBUTORS @@ -1,13 +1,19 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/CONTRIBUTORS,v $ +# ## Authors and actives contributors to SMBLDAP-TOOLS Have contributed directly to this tools, or are always in charge of -some aspects of it developments (alphabetical order): +some aspects of it developments: + . Jérôme Tournier . Terry Davis . David Le Corfec . Olivier Lemaire - . Jérôme Tournier Many thanks to contributors for bug report and patches: + . Marc Schoechlin + load the perl-modules without setting environment-variables or making symlinks + . Alexander Bergolth + more Net::LDAP support . Gert-Jan Braas bug report for 2.2.3 samba.schema . Jody Haynes diff --git a/examples/LDAP/smbldap-tools/ChangeLog b/examples/LDAP/smbldap-tools/ChangeLog index 0994cb4931..e4e3768385 100644 --- a/examples/LDAP/smbldap-tools/ChangeLog +++ b/examples/LDAP/smbldap-tools/ChangeLog @@ -1,28 +1,89 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/ChangeLog,v $ +# $id: $ +# ## ChangeLog for SMBLDAP-TOOLS -* 2002-07-24: top and account objectclasses replaced with inetorgperson -* 2002-06-03: notes to webmin.idealx.org (idxldapaccounts) -* 2002-06-01: release 0.7. tested with 2.2.4 -* 2002-05-31: fixed smbldap-populate compliance to smbldap_conf - cleaned up smbldap_conf to be more readable - some more documentation - bugfixes on smbldap-passwd and smbldap-populate -* 2002-05-16: modified default mode on homes: now 700 -* 2002-05-13: fixed spec (relocation and reqs) -* 2002-03-02: fixed 2.2.3 sambaAccount bug with smbldap-useradd.pl +2003-11-18: + . new option '-a' to smbldap-usermod.pl that allow adding the sambaSamAccount + objectclass to an existing posixAccount +2003-11-07: + . patch that allow adding user to a group when the group is in a higher level depth + then ou=Groups (for example, ou=grp1,ou=Groups,...) + . check the unicity of a group when adding/removing a user to this group +2003-10-28: + . new option '-p' in smbldap-groupadd.pl to 'print' the gidNumber + of the group to STDOUT. This is needed by samba (see the man page) +2003-10-19: + . new function does_sid_exist that check if samaSID sttribute is already + defined for another use or another group +2003-10-13: + . smbldap-populate.pl now also add the group mapping +2003-10-01: + . one can now comment the two directives '$_userSmbHome' and '$_userProfile' + if you want to use the smb.conf directives instead ('logon home' and + 'logon path' respectively), or if you want to desable roaming profiles + . Patch from Alexander Bergolth : the sambaPrimaryGroupSID + of a user is now set to the sambaSID of his primary group +2003-09-29: + . added new option '$_defaultMaxPasswordAge' in smbldap_conf.pm to specifie + how long a password is valid + . The '-B' option was not always valid: to force a user to change his password: + . the attribut sambaPwdLastSet must be != 0 + . the attribut sambaAcctFlags must not match the 'X' flag + . logon script is set (for every one) to the default '_userScript' value if it is defined + . Patch from Alexander Bergolth : + gid-sid group mapping to smbldap-groupadd.pl and smbldap-groupmod.pl +2003-09-19: Patch from Marc Schoechlin + . load the perl-modules without setting environment-variables or making symlinks +2003-09-18: Patch from Alexander Bergolth + . options "-u", "-g", "-s" and "-c" are now functionnal + . the existence of samba account was made on sambaAccount and + not sambaSamAccount as it should be for samba3 + . new function read_user_entry to smbldap_tools.pm that returns + a Net::LDAP:Entry object of the user + . Use this object to get the dn and user attributes instead of + producing an ldif and searching for attributes within that ldif +2003-09-15: + . change machine account creation to not add the sambaSamAccount objectclass. + It is now added directly by samba when joigning the domain + . new option in smbldap-usermod.pl: '-e' to set an expire date + . Start_tls support activated when ldapSSL is set to 1 + . Net::LDAP support more scripts + . bugs correction +2003-09-02: + . sambaPwdLastSet is updated when smbldap-passwd.pl is used + . add a function is_group_member to test the existence of a + user in a particular group + . add a function is_unix_user to test if a particular user exist + . Net::LDAP support more scripts +2003-08-15: + . Samba3.0 support +2003-08-01: + . Final version for samba 2.2.8a (cvs tag SAMBA-2-2-8a-FINAL) + . OpenLDAP 2.1 support (only one structural objectclass allowed) +2002-07-24: top and account objectclasses replaced with inetorgperson +2002-06-03: notes to webmin.idealx.org (idxldapaccounts) +2002-06-01: release 0.7. tested with 2.2.4 +2002-05-31: fixed smbldap-populate compliance to smbldap_conf + cleaned up smbldap_conf to be more readable + some more documentation + bugfixes on smbldap-passwd and smbldap-populate +2002-05-16: modified default mode on homes: now 700 +2002-05-13: fixed spec (relocation and reqs) +2002-03-02: fixed 2.2.3 sambaAccount bug with smbldap-useradd.pl (rid is now mandatory in the sambaAccount objectClass) -* 2002-02-14: just modified default populate for Administrator -* 2002-02-05: release 0.6. enable/disable user in usermod -* 2002-02-04: release 0.5. added smbldap-migrate-groups to migrate NT groups - from a net group dump. added samba parameters to smbldap-useradd - and smbldap-usermod. -* 2002-01-12: added smbldap-migrate-accounts to migrate users/machines - accounts from a PWDUMP dump -* 2001-12-13: added smbldap-populate to create the initial base -* 2001-12-13: initial release 0.1 -* 2001-12-12: fixed the SPEC file for RedHat -* 2001-12-03: cleaned the code and use strict; -* 2001-11-20: initial needs (for testing purpose on Samba-2.2.2 an Samba-TNG) +2002-02-14: just modified default populate for Administrator +2002-02-05: release 0.6. enable/disable user in usermod +2002-02-04: release 0.5. added smbldap-migrate-groups to migrate NT groups + from a net group dump. added samba parameters to smbldap-useradd + and smbldap-usermod. +2002-01-12: added smbldap-migrate-accounts to migrate users/machines + accounts from a PWDUMP dump +2001-12-13: added smbldap-populate to create the initial base +2001-12-13: initial release 0.1 +2001-12-12: fixed the SPEC file for RedHat +2001-12-03: cleaned the code and use strict; +2001-11-20: initial needs (for testing purpose on Samba-2.2.2 an Samba-TNG) # - The End diff --git a/examples/LDAP/smbldap-tools/FILES b/examples/LDAP/smbldap-tools/FILES index 0343c53d60..48ee571b29 100644 --- a/examples/LDAP/smbldap-tools/FILES +++ b/examples/LDAP/smbldap-tools/FILES @@ -1,3 +1,5 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/FILES,v $ +# ## File listing for SMBLDAP-TOOLS CONTRIBUTORS : authors and contributors diff --git a/examples/LDAP/smbldap-tools/INFRASTRUCTURE b/examples/LDAP/smbldap-tools/INFRASTRUCTURE index 25fbda8599..e14ec70e02 100644 --- a/examples/LDAP/smbldap-tools/INFRASTRUCTURE +++ b/examples/LDAP/smbldap-tools/INFRASTRUCTURE @@ -1,3 +1,5 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/INFRASTRUCTURE,v $ +# ## Some notes about the architecture @@ -41,6 +43,15 @@ man smb.conf for more): domain admin group = " @"Domain Admins" " +However, to make pdb_ldap accept bind without being uid=0, a quick and +dirty patch must be applied to 2.2.4 (see samba-2.2.4-ldapbindnotuid0.patch). +This patch is Q&D because the check is there because Samba store admin +credentials to establish the LDAP connection. The uid == 0 check was to +ensure that a normal user could not get write access to the LDAP backend. +A more logical situation should be done for 2.2.5 by checking if the user +is a member of the domain admin group (reported to Jerremy and Gerald +2002-05-28). + Other built in groups are really cosmetic ones with Samba 2.2.x. We did not removed them because one of these days, we whish to use Samba 3.0 where Windows Group Support should be operational. diff --git a/examples/LDAP/smbldap-tools/INSTALL b/examples/LDAP/smbldap-tools/INSTALL index d5ca07826f..f4c72751a7 100644 --- a/examples/LDAP/smbldap-tools/INSTALL +++ b/examples/LDAP/smbldap-tools/INSTALL @@ -1,3 +1,5 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/INSTALL,v $ +# ## How To Install SMBLDAP-TOOLS Quick & Dirty: diff --git a/examples/LDAP/smbldap-tools/Makefile b/examples/LDAP/smbldap-tools/Makefile index 3e5eac427d..783a3571a9 100644 --- a/examples/LDAP/smbldap-tools/Makefile +++ b/examples/LDAP/smbldap-tools/Makefile @@ -1,5 +1,5 @@ PACKAGE=smbldap-tools -RELEASE=0.7 +RELEASE=0.8.2-1 DESTDIR = $(PACKAGE)-$(RELEASE) dist: distclean $(DESTDIR).tgz diff --git a/examples/LDAP/smbldap-tools/README b/examples/LDAP/smbldap-tools/README index 3b4bf2da0d..add0175c0c 100644 --- a/examples/LDAP/smbldap-tools/README +++ b/examples/LDAP/smbldap-tools/README @@ -1,3 +1,6 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/README,v $ +# + Latest version may be found at http://samba.idealx.org/ diff --git a/examples/LDAP/smbldap-tools/TODO b/examples/LDAP/smbldap-tools/TODO index 25cc30c684..71e6695299 100644 --- a/examples/LDAP/smbldap-tools/TODO +++ b/examples/LDAP/smbldap-tools/TODO @@ -1,3 +1,5 @@ +# $Source: /data/src/mirror/cvs/samba/examples/LDAP/smbldap-tools/TODO,v $ +# ## TODO list - First In, Last in the list... ## (BF: Bug Report / FR: Feature Request) diff --git a/examples/LDAP/smbldap-tools/smbldap-groupadd.pl b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl index 91cd2dad53..e242d6e223 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupadd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupadd.pl @@ -27,33 +27,104 @@ use FindBin; use FindBin qw($RealBin); use lib "$RealBin/"; use smbldap_tools; - +use smbldap_conf; use Getopt::Std; my %Options; -my $ok = getopts('og:?', \%Options); +my $ok = getopts('ag:or:s:t:p?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-go?] groupname\n"; - print " -g gid\n"; - print " -o gid is not unique\n"; - print " -? show this help message\n"; - exit (1); + print "Usage: $0 [-agorst?] groupname\n"; + print " -a add automatic group mapping entry\n"; + print " -g gid\n"; + print " -o gid is not unique\n"; + print " -r group-rid\n"; + print " -s group-sid\n"; + print " -t group-type\n"; + print " -p print the gidNumber to stdout\n"; + print " -? show this help message\n"; + exit (1); } my $_groupName = $ARGV[0]; if (defined(get_group_dn($_groupName))) { - print "$0: group $_groupName exists\n"; - exit (6); + warn "$0: group $_groupName exists\n"; + exit (6); } my $_groupGidNumber = $Options{'g'}; +if (! defined ($_groupGidNumber = group_add($_groupName, $_groupGidNumber, $Options{'o'}))) { + warn "$0: error adding group $_groupName\n"; + exit (6); +} + +my $group_sid; +my $tmp; +if ($tmp= $Options{'s'}) { + if ($tmp =~ /^S-(?:\d+-)+\d+$/) { + $group_sid = $tmp; + } else { + warn "$0: illegal group-rid $tmp\n"; + exit(7); + } +} elsif ($Options{'r'} || $Options{'a'}) { + my $group_rid; + if ($tmp= $Options{'r'}) { + if ($tmp =~ /^\d+$/) { + $group_rid = $tmp; + } else { + warn "$0: illegal group-rid $tmp\n"; + exit(7); + } + } else { + # algorithmic mapping + $group_rid = 2*$_groupGidNumber+1001; + } + $group_sid = $SID.'-'.$group_rid; +} -if (!group_add($_groupName, $_groupGidNumber, $Options{'o'})) { - print "$0: error adding group $_groupName\n"; - exit (6); +if ($Options{'r'} || $Options{'a'} || $Options{'s'}) { + # let's test if this SID already exist + my $test_exist_sid=does_sid_exist($group_sid,$groupsdn); + if ($test_exist_sid->count == 1) { + warn "Group SID already owned by\n"; + # there should not exist more than one entry, but ... + foreach my $entry ($test_exist_sid->all_entries) { + my $dn= $entry->dn; + chomp($dn); + warn "$dn\n"; + } + exit(7); + } } +if ($group_sid) { + my $group_type; + my $tmp; + if ($tmp= $Options{'t'}) { + unless (defined($group_type = &group_type_by_name($tmp))) { + warn "$0: unknown group type $tmp\n"; + exit(8); + } + } else { + $group_type = group_type_by_name('domain'); + } + my $ldap_master=connect_ldap_master(); + my $modify = $ldap_master->modify ( "cn=$_groupName,$groupsdn", + add => { + 'objectClass' => 'sambaGroupMapping', + 'sambaSID' => $group_sid, + 'sambaGroupType' => $group_type + } + ); + $modify->code && warn "failed to delete entry: ", $modify->error ; + # take down session + $ldap_master->unbind +} + +if ($Options{'p'}) { + print STDOUT "$_groupGidNumber"; +} exit(0); ######################################## diff --git a/examples/LDAP/smbldap-tools/smbldap-groupdel.pl b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl index 89d0d993ac..4f6839ebe5 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupdel.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupdel.pl @@ -30,23 +30,22 @@ use smbldap_tools; use smbldap_conf; ##################### - use Getopt::Std; my %Options; my $ok = getopts('?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 groupname\n"; - print " -? show this help message\n"; - exit (1); + print "Usage: $0 groupname\n"; + print " -? show this help message\n"; + exit (1); } my $_groupName = $ARGV[0]; my $dn_line; if (!defined($dn_line = get_group_dn($_groupName))) { - print "$0: group $_groupName doesn't exist\n"; - exit (6); + print "$0: group $_groupName doesn't exist\n"; + exit (6); } my $dn = get_dn_from_line($dn_line); @@ -56,7 +55,7 @@ group_del($dn); my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; if ($nscd_status == 0) { - system "/etc/init.d/nscd restart > /dev/null 2>&1"; + system "/etc/init.d/nscd restart > /dev/null 2>&1"; } #if (defined($dn_line = get_group_dn($_groupName))) { diff --git a/examples/LDAP/smbldap-tools/smbldap-groupmod.pl b/examples/LDAP/smbldap-tools/smbldap-groupmod.pl index f897101602..3f9741e015 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupmod.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupmod.pl @@ -1,4 +1,5 @@ #!/usr/bin/perl -w + # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -29,29 +30,33 @@ use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; - ##################### use Getopt::Std; my %Options; -my $ok = getopts('og:n:m:x:?', \%Options); +my $ok = getopts('ag:n:m:or:s:t:x:?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-g gid [-o]] [-n name] [-m members(,)] [-x members (,)] groupname\n"; - print " -g new gid\n"; - print " -o gid is not unique\n"; - print " -n new group name\n"; - print " -m add members (comma delimited)\n"; - print " -x delete members (comma delimted)\n"; - print " -? show this help message\n"; - exit (1); + print "Usage: $0 [-a] [-g gid [-o]] [-n name] [-m members(,)] [-x members (,)] [-r rid] [-s sid] [-t type] groupname\n"; + print " -a add automatic group mapping entry\n"; + print " -g new gid\n"; + print " -o gid is not unique\n"; + print " -n new group name\n"; + print " -m add members (comma delimited)\n"; + print " -r group-rid\n"; + print " -s group-sid\n"; + print " -t group-type\n"; + print " -x delete members (comma delimted)\n"; + print " -? show this help message\n"; + exit (1); } my $groupName = $ARGV[0]; +my $group_entry; -if (!defined(get_group_dn($groupName))) { - print "$0: group $groupName doesn't exist\n"; - exit (6); +if (! ($group_entry = read_group_entry($groupName))) { + print "$0: group $groupName doesn't exist\n"; + exit (6); } my $newname = $Options{'n'}; @@ -59,20 +64,24 @@ my $newname = $Options{'n'}; my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; if ($nscd_status == 0) { - system "/etc/init.d/nscd restart > /dev/null 2>&1"; + system "/etc/init.d/nscd restart > /dev/null 2>&1"; } my $gid = getgrnam($groupName); +unless (defined ($gid)) { + print "$0: group $groupName not found!\n"; + exit(6); +} my $tmp; if (defined($tmp = $Options{'g'}) and $tmp =~ /\d+/) { - if (!defined($Options{'o'})) { + if (!defined($Options{'o'})) { if (defined(getgrgid($tmp))) { - print "$0: gid $tmp exists\n"; - exit (6); + print "$0: gid $tmp exists\n"; + exit (6); } - } - if (!($gid == $tmp)) { + } + if (!($gid == $tmp)) { my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn", changes => [ @@ -82,7 +91,7 @@ if (defined($tmp = $Options{'g'}) and $tmp =~ /\d+/) { $modify->code && die "failed to modify entry: ", $modify->error ; # take down session $ldap_master->unbind - } + } } @@ -101,17 +110,19 @@ if (defined($newname)) { # Add members if (defined($Options{'m'})) { - my $members = $Options{'m'}; - my @members = split( /,/, $members ); - my $member; - foreach $member ( @members ) { + my $members = $Options{'m'}; + my @members = split( /,/, $members ); + my $member; + foreach $member ( @members ) { + my $group_entry=read_group_entry($groupName); + $groupsdn=$group_entry->dn; if (is_unix_user($member)) { - if (is_group_member("cn=$groupName,$groupsdn",$member)) { + if (is_group_member($groupsdn,$member)) { print "User $member already in the group\n"; } else { print "adding user $member to group $groupName\n"; my $ldap_master=connect_ldap_master(); - my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn", + my $modify = $ldap_master->modify ($groupsdn, changes => [ add => [memberUid => $member] ] @@ -123,19 +134,21 @@ if (defined($Options{'m'})) { } else { print "User $member does not exist: create it first !\n"; } - } + } } # Delete members if (defined($Options{'x'})) { - my $members = $Options{'x'}; - my @members = split( /,/, $members ); - my $member; - foreach $member ( @members ) { - if (is_group_member("cn=$groupName,$groupsdn",$member)) { + my $members = $Options{'x'}; + my @members = split( /,/, $members ); + my $member; + foreach $member ( @members ) { + my $group_entry=read_group_entry($groupName); + $groupsdn=$group_entry->dn; + if (is_group_member("$groupsdn",$member)) { print "deleting user $member from group $groupName\n"; my $ldap_master=connect_ldap_master(); - my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn", + my $modify = $ldap_master->modify ($groupsdn, changes => [ delete => [memberUid => $member] ] @@ -146,13 +159,73 @@ if (defined($Options{'x'})) { } else { print "User $member is not in the group $groupName!\n"; } - } + } +} + +my $group_sid; +if ($tmp= $Options{'s'}) { + if ($tmp =~ /^S-(?:\d+-)+\d+$/) { + $group_sid = $tmp; + } else { + print "$0: illegal group-rid $tmp\n"; + exit(7); + } +} elsif ($Options{'r'} || $Options{'a'}) { + my $group_rid; + if ($tmp= $Options{'r'}) { + if ($tmp =~ /^\d+$/) { + $group_rid = $tmp; + } else { + print "$0: illegal group-rid $tmp\n"; + exit(7); + } + } else { + # algorithmic mapping + $group_rid = 2*$gid+1001; + } + $group_sid = $SID.'-'.$group_rid; +} + +if ($group_sid) { + my @adds; + my @mods; + push(@mods, 'sambaSID' => $group_sid); + + if ($tmp= $Options{'t'}) { + my $group_type; + if (defined($group_type = &group_type_by_name($tmp))) { + push(@mods, 'sambaGroupType' => $group_type); + } else { + print "$0: unknown group type $tmp\n"; + exit(8); + } + } else { + if (! defined($group_entry->get_value('sambaGroupType'))) { + push(@mods, 'sambaGroupType' => group_type_by_name('domain')); + } + } + + my @oc = $group_entry->get_value('objectClass'); + unless (grep($_ =~ /^sambaGroupMapping$/i, @oc)) { + push (@adds, 'objectClass' => 'sambaGroupMapping'); + } + + my $ldap_master=connect_ldap_master(); + my $modify = $ldap_master->modify ( "cn=$groupName,$groupsdn", + changes => [ + 'add' => [ @adds ], + 'replace' => [ @mods ] + ] + ); + $modify->code && warn "failed to delete entry: ", $modify->error ; + # take down session + $ldap_master->unbind } $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; if ($nscd_status == 0) { - system "/etc/init.d/nscd restart > /dev/null 2>&1"; + system "/etc/init.d/nscd restart > /dev/null 2>&1"; } exit (0); @@ -161,19 +234,19 @@ exit (0); =head1 NAME - smbldap-groupmod.pl - Modify a group +smbldap-groupmod.pl - Modify a group =head1 SYNOPSIS - smbldap-groupmod.pl [-g gid [-o]] [-n group_name ] group +smbldap-groupmod.pl [-g gid [-o]] [-n group_name ] group =head1 DESCRIPTION - The smbldap-groupmod.pl command modifies the system account files to - reflect the changes that are specified on the command line. - The options which apply to the smbldap-groupmod command are +The smbldap-groupmod.pl command modifies the system account files to + reflect the changes that are specified on the command line. + The options which apply to the smbldap-groupmod command are - -g gid The numerical value of the group's ID. This value must be + -g gid The numerical value of the group's ID. This value must be unique, unless the -o option is used. The value must be non- negative. Any files which the old group ID is the file group ID must have the file group ID changed manually. diff --git a/examples/LDAP/smbldap-tools/smbldap-groupshow.pl b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl index 18fe082e66..a9d368763e 100755 --- a/examples/LDAP/smbldap-tools/smbldap-groupshow.pl +++ b/examples/LDAP/smbldap-tools/smbldap-groupshow.pl @@ -36,8 +36,8 @@ my %Options; my $ok = getopts('?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-?] group\n"; - print " -? show this help message\n"; + print "Usage: $0 [-?] group\n"; + print " -? show this help message\n"; exit (1); } diff --git a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl index 86f52cb53e..54e4d7f7e3 100755 --- a/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl +++ b/examples/LDAP/smbldap-tools/smbldap-migrate-accounts.pl @@ -39,14 +39,14 @@ use smbldap_conf; # Errors, debug and stats are output to stderr. sub modify_account -{ - my ($login, $basedn, $lmpwd, $ntpwd, $gecos, $homedir) = @_; + { + my ($login, $basedn, $lmpwd, $ntpwd, $gecos, $homedir) = @_; # bind to a directory with dn and password my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->modify ("uid=$login,$basedn", changes => [ - replace => [lmpassword => "$lmpwd"], - replace => [ntpassword => "$ntpwd"], + replace => [sambaLMPassword => "$lmpwd"], + replace => [sambaNTpassword => "$ntpwd"], replace => [gecos => "$gecos"], replace => [sambaHomePath => "$homedir"] ] @@ -54,7 +54,7 @@ sub modify_account $modify->code && die "failed to modify entry: ", $modify->error ; # take down the session $ldap_master->unbind; -} + } ##################### @@ -64,15 +64,15 @@ my %Options; my $ok = getopts('awA:CUW:?h', \%Options); if ( (!$ok) || ($Options{'?'}) || ($Options{'h'}) ) { - print "Usage: $0 [-awAWCU?]\n"; - print " -a process only people, ignore computers\n"; - print " -w process only computers, ignore persons\n"; - print " -A option string passed verbatim to smbldap-useradd for persons\n"; - print " -W option string passed verbatim to smbldap-useradd for computers\n"; - print " -C if entry not found, don't create it and log it to stdout (default: create it)\n"; - print " -U if entry found, don't update it and log it to stdout (default: update it)\n"; + print "Usage: $0 [-awAWCU?]\n"; + print " -a process only people, ignore computers\n"; + print " -w process only computers, ignore persons\n"; + print " -A option string passed verbatim to smbldap-useradd for persons\n"; + print " -W option string passed verbatim to smbldap-useradd for computers\n"; + print " -C if entry not found, don't create it and log it to stdout (default: create it)\n"; + print " -U if entry found, don't update it and log it to stdout (default: update it)\n"; print " -?|-h show this help message\n"; - exit (1); + exit (1); } my %processed = ( 'user' => 0, 'machine' => 0); @@ -90,7 +90,7 @@ while (<>) { my $entry_type = 'user'; - if ($login =~ m/.*\$$/ ) { # computer + if ($login =~ m/.*\$$/ ) { # computer $processed{'machine'}++; $entry_type = 'machine'; if (defined($Options{'a'})) { @@ -117,14 +117,14 @@ while (<>) { } # normalize homedir -# uncomment to replace configured share with share from pwdump -# if ($homedir eq "") { - $homedir = $_userSmbHome; -# } + # uncomment to replace configured share with share from pwdump + # if ($homedir eq "") { + $homedir = $_userSmbHome; + # } # normalize gecos if (!($gecos eq "")) { - $gecos =~ tr/ÃÀÂÄáàâäÇçÉÈÊËÆéèêëæÃÃŒÃÎíìîÃÑñÓÒÔÖóòôöÚÙÜÛúùüûÃýÿ/AAAAaaaaCcEEEEEeeeeeIIIIiiiiNnOOOOooooUUUUuuuuYyy/; + $gecos =~ tr/ÁÀÂÄáàâäÇçÉÈÊËÆéèêëæÍÌÏÎíìîÏÑñÓÒÔÖóòôöÚÙÜÛúùüûÝýÿ/AAAAaaaaCcEEEEEeeeeeIIIIiiiiNnOOOOooooUUUUuuuuYyy/; } else { $gecos = $_userGecos; } @@ -141,12 +141,12 @@ while (<>) { print STDERR "error adding $login, skipping\n"; next; } - # lem modif... a retirer si pb + # lem modif... a retirer si pb if ($entry_type eq "user") { modify_account($login, $userbasedn, $lmpwd, $ntpwd, $gecos, $homedir); - } + } - $created{$entry_type}++; + $created{$entry_type}++; } else { # uid doesn't exist and no create => log print "$_"; $logged{$entry_type}++; @@ -187,7 +187,7 @@ print STDERR "special users skipped: $specialskipped\n"; =head1 NAME - smbldap-migrate.pl - Migrate NT accounts to LDAP +smbldap-migrate.pl - Migrate NT accounts to LDAP =head1 SYNOPSIS diff --git a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl index c60be18caf..a2b07bf817 100644 --- a/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl +++ b/examples/LDAP/smbldap-tools/smbldap-migrate-groups.pl @@ -33,52 +33,50 @@ use smbldap_tools; use smbldap_conf; use Getopt::Std; - - sub process_rec_group -{ + { my ($group, $mb) = @_; my @members; if (!(@members = group_get_members($group))) { - return 0; + return 0; } foreach my $m (@members) { - if ( !($m =~ m/^\*/) ) { + if ( !($m =~ m/^\*/) ) { push @{$mb}, $m; - } else { + } else { my $gname = $m; $gname =~ s/^.//; if (!process_rec_group($gname, $mb)) { - print "recursive group not added : $gname\n"; + print "recursive group not added : $gname\n"; } - } + } } -} + } # given a group dn and a list of members, update the group sub modify_group -{ + { my ($group, $dn_line, @members, $recgroup) = @_; my $m; my @new_mb; foreach $m (@members) { - if ( ($m =~ m/^\*/) ) { + if ( ($m =~ m/^\*/) ) { my $gname = $m; $gname =~ s/^.//; if (!$recgroup) { - print "recursive group not added : $gname\n"; + print "recursive group not added : $gname\n"; } else { - if (!process_rec_group($gname, \@new_mb)) { + if (!process_rec_group($gname, \@new_mb)) { print "recursive group not added : $gname\n"; - } + } } - } else { + } else { push @new_mb, $m; - } + } } # new_mb contains flat members from group dump @@ -94,7 +92,7 @@ sub modify_group my $mbs; foreach $m (@new_mb) { - $mbs .= "memberUid: $m\n"; + $mbs .= "memberUid: $m\n"; } my $mods="$dn_line @@ -105,16 +103,16 @@ $mbs #print "$mods\n"; my $tmpldif = -"$mods + "$mods "; die "$0: error while modifying group $group\n" - unless (do_ldapmodify($tmpldif) == 0); + unless (do_ldapmodify($tmpldif) == 0); undef $tmpldif; -} + } sub display_group -{ + { my ($group, @members) = @_; print "Group name $group\n"; @@ -122,43 +120,43 @@ sub display_group my $m; my $i = 0; foreach $m (@members) { - print "$m "; - if ($i % 5 == 0) { + print "$m "; + if ($i % 5 == 0) { print "\n"; - } - $i++; + } + $i++; } -} + } sub process_group -{ + { my ($group, @members, $nocreate, $noupdate, $recgroup) = @_; my $dn_line; if (!defined($dn_line = get_group_dn($group))) { - # group not found, create it ? - if (!$nocreate) { + # group not found, create it ? + if (!$nocreate) { system "/usr/local/sbin/smbldap-groupadd.pl \"$group\"; sleep 5"; if (!defined($dn_line = get_group_dn($group))) { - return 1; + return 1; } modify_group($group, $dn_line, @members, $recgroup); - } else { + } else { # don't create print "not created:\n"; display_group($group, @members); - } + } } else { - # group found, update it ? - if (!$noupdate) { + # group found, update it ? + if (!$noupdate) { modify_group($group, $dn_line, @members, $recgroup); - } else { + } else { # don't update print "not updated:\n"; display_group($group, @members); - } + } } -} + } ################################################### @@ -166,11 +164,11 @@ my %Options; my $ok = getopts('CUr?', \%Options); if ( (!$ok) || ($Options{'?'}) ) { - print "Usage: $0 [-CUr?] < group_dump\n"; - print " -C don't create group if it doesn't exist\n"; - print " -U don't update group if it exists\n"; - print " -r recursively process groups\n"; - exit(1); + print "Usage: $0 [-CUr?] < group_dump\n"; + print " -C don't create group if it doesn't exist\n"; + print " -U don't update group if it exists\n"; + print " -r recursively process groups\n"; + exit(1); } my $group_name; @@ -184,13 +182,13 @@ while (<>) { next if ( $line =~ m/^\s*$/ ); if ($group_name eq "") { - if ( $line =~ m/^Group name\s+(.+).$/ ) { + if ( $line =~ m/^Group name\s+(.+).$/ ) { $group_name = $1; next; - } + } } if ($group_desc eq "") { - if ( $line =~ m/^Comment\s+(.*)$/ ) { + if ( $line =~ m/^Comment\s+(.*)$/ ) { $group_desc = $1; next; } diff --git a/examples/LDAP/smbldap-tools/smbldap-passwd.pl b/examples/LDAP/smbldap-tools/smbldap-passwd.pl index 7845e5548e..afbc87a058 100755 --- a/examples/LDAP/smbldap-tools/smbldap-passwd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-passwd.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl -w # LDAP to unix password sync script for samba -# + # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -23,7 +23,7 @@ # USA. # Purpose : -# . ldap-unix passwd sync for SAMBA-2.2.2 + LDAP +# . ldap-unix passwd sync for SAMBA>2.2.2 + LDAP # . may also replace /bin/passwd use strict; @@ -40,29 +40,29 @@ my $ret; my $arg; foreach $arg (@ARGV) { - if ($< != 0) { - die "Only root can specify parameters\n"; - } else { - if ( ($arg eq '-?') || ($arg eq '--help') ) { - print "Usage: $0 [username]\n"; - print " -?, --help show this help message\n"; - exit (6); - } elsif (substr($arg,0) ne '-') { - $user = $arg; - } - $oldpass = 1; + if ($< != 0) { + die "Only root can specify parameters\n"; + } else { + if ( ($arg eq '-?') || ($arg eq '--help') ) { + print "Usage: $0 [username]\n"; + print " -?, --help show this help message\n"; + exit (6); + } elsif (substr($arg,0) ne '-') { + $user = $arg; } + $oldpass = 1; + } } if (!defined($user)) { - $user=$ENV{"USER"}; + $user=$ENV{"USER"}; } # test existence of user in LDAP my $dn_line; if (!defined($dn_line = get_user_dn($user))) { - print "$0: user $user doesn't exist\n"; - exit (10); + print "$0: user $user doesn't exist\n"; + exit (10); } my $dn = get_dn_from_line($dn_line); @@ -73,17 +73,17 @@ print "Changing password for $user\n"; # non-root user if (!defined($oldpass)) { - # prompt for current password - system "stty -echo"; - print "(current) UNIX password: "; - chomp($oldpass=); - print "\n"; - system "stty echo"; - - if (!is_user_valid($user, $dn, $oldpass)) { - print "Authentication failure\n"; - exit (10); - } + # prompt for current password + system "stty -echo"; + print "(current) UNIX password: "; + chomp($oldpass=); + print "\n"; + system "stty echo"; + + if (!is_user_valid($user, $dn, $oldpass)) { + print "Authentication failure\n"; + exit (10); + } } # prompt for new password @@ -104,8 +104,8 @@ print "\n"; system "stty echo"; if ($pass ne $pass2) { - print "New passwords don't match!\n"; - exit (10); + print "New passwords don't match!\n"; + exit (10); } # First, connecting to the directory @@ -113,59 +113,64 @@ my $ldap_master=connect_ldap_master(); # only modify smb passwords if smb user if ($samba == 1) { - if (!$with_smbpasswd) { -# generate LanManager and NT clear text passwords + if (!$with_smbpasswd) { + # generate LanManager and NT clear text passwords if ($mk_ntpasswd eq '') { - print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; - exit(1); + print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; + exit(1); } my $ntpwd = `$mk_ntpasswd '$pass'`; - chomp(my $sambaLMPassword = substr($ntpwd, 0, index($ntpwd, ':'))); - chomp(my $sambaNTPassword = substr($ntpwd, index($ntpwd, ':')+1)); + chomp(my $sambaLMPassword = substr($ntpwd, 0, index($ntpwd, ':'))); + chomp(my $sambaNTPassword = substr($ntpwd, index($ntpwd, ':')+1)); # the sambaPwdLastSet must be updating my $date=time; + my @mods; + push(@mods, 'sambaLMPassword' => $sambaLMPassword); + push(@mods, 'sambaNTPassword' => $sambaNTPassword); + push(@mods, 'sambaPwdLastSet' => $date); + if (defined $_defaultMaxPasswordAge) { + my $new_sambaPwdMustChange=$date+$_defaultMaxPasswordAge*24*60*60; + push(@mods, 'sambaPwdMustChange' => $new_sambaPwdMustChange); + push(@mods, 'sambaAcctFlags' => '[U]'); + } # Let's change nt/lm passwords my $modify = $ldap_master->modify ( "$dn", - changes => [ - replace => [sambaLMPassword => "$sambaLMPassword"], - replace => [sambaNTPassword => "$sambaNTPassword"], - replace => [sambaPwdLastSet => "$date"] - ] + 'replace' => { @mods } ); $modify->code && warn "failed to modify entry: ", $modify->error ; } else { if ($< != 0) { - my $FILE="|$smbpasswd -s >/dev/null"; - open (FILE, $FILE) || die "$!\n"; - print FILE <modify ( "$dn", - changes => [ - replace => [userPassword => "$hash_password"] - ] - ); + changes => [ + replace => [userPassword => "$hash_password"] + ] + ); $modify->code && warn "Unable to change password : ", $modify->error ; # take down session @@ -186,7 +191,7 @@ smbldap-passwd.pl - change user password =head1 DESCRIPTION - smbldap-passwd.pl changes passwords for user accounts. A normal user +smbldap-passwd.pl changes passwords for user accounts. A normal user may only change the password for their own account, the super user may change the password for any account. diff --git a/examples/LDAP/smbldap-tools/smbldap-populate.pl b/examples/LDAP/smbldap-tools/smbldap-populate.pl index ce497672a9..b691a84850 100755 --- a/examples/LDAP/smbldap-tools/smbldap-populate.pl +++ b/examples/LDAP/smbldap-tools/smbldap-populate.pl @@ -2,6 +2,7 @@ # Populate a LDAP base for Samba-LDAP usage # + # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # @@ -39,66 +40,66 @@ use vars qw(%oc); # objectclass of the suffix %oc = ( - "ou" => "organizationalUnit", - "o" => "organization", - "dc" => "dcObject", -); + "ou" => "organizationalUnit", + "o" => "organization", + "dc" => "dcObject", + ); my %Options; my $ok = getopts('a:b:?', \%Options); if ( (!$ok) || ($Options{'?'}) ) { - print "Usage: $0 [-ab?] [ldif]\n"; - print " -a administrator login name (default: Administrator)\n"; - print " -b guest login name (default: nobody)\n"; - print " -? show this help message\n"; - print " ldif file to add to ldap (default: suffix, Groups,"; - print " Users, Computers and builtin users )\n"; - exit (1); + print "Usage: $0 [-ab?] [ldif]\n"; + print " -a administrator login name (default: Administrator)\n"; + print " -b guest login name (default: nobody)\n"; + print " -? show this help message\n"; + print " ldif file to add to ldap (default: suffix, Groups,"; + print " Users, Computers and builtin users )\n"; + exit (1); } my $_ldifName; my $tmp_ldif_file="/tmp/$$.ldif"; if (@ARGV >= 1) { - $_ldifName = $ARGV[0]; + $_ldifName = $ARGV[0]; } my $adminName = $Options{'a'}; if (!defined($adminName)) { - $adminName = "Administrator"; + $adminName = "Administrator"; } my $guestName = $Options{'b'}; if (!defined($guestName)) { - $guestName = "nobody"; + $guestName = "nobody"; } if (!defined($_ldifName)) { - my $attr; - my $val; - my $objcl; + my $attr; + my $val; + my $objcl; print "Using builtin directory structure\n"; - if ($suffix =~ m/([^=]+)=([^,]+)/) { + if ($suffix =~ m/([^=]+)=([^,]+)/) { $attr = $1; $val = $2; $objcl = $oc{$attr} if (exists $oc{$attr}); if (!defined($objcl)) { - $objcl = "myhardcodedobjectclass"; + $objcl = "myhardcodedobjectclass"; } - } else { + } else { die "can't extract first attr and value from suffix $suffix"; - } - #print "$attr=$val\n"; - my ($organisation,$ext) = ($suffix =~ m/dc=(\w+),dc=(\w+)$/); + } + #print "$attr=$val\n"; + my ($organisation,$ext) = ($suffix =~ m/dc=(.*),dc=(.*)$/); - #my $FILE="|cat"; + #my $FILE="|cat"; my $FILE=$tmp_ldif_file; open (FILE, ">$FILE") || die "Can't open file $FILE: $!\n"; - print FILE <= 5.6 @@ -86,13 +88,21 @@ install -m 644 %{SOURCE14} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/FILES install -m 644 %{SOURCE15} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/README install -m 644 %{SOURCE16} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/TODO install -m 644 %{SOURCE21} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/INFRA +install -m 644 %{SOURCE22} $RPM_BUILD_ROOT/usr/share/doc/smbldap-tools/smb.conf %clean rm -rf $RPM_BUILD_ROOT %post -ln -sf %{prefix}/sbin/smbldap_tools.pm /usr/lib/perl5/site_perl/smbldap_tools.pm -ln -sf %{prefix}/sbin/smbldap_conf.pm /usr/lib/perl5/site_perl/smbldap_conf.pm +# from smbldap-tools-0.8-2, librairies are loaded with the FindBin perl package +if [ -f /usr/lib/perl5/site_perl/smbldap_tools.pm ]; +then + rm -f /usr/lib/perl5/site_perl/smbldap_tools.pm +fi +if [ -f /usr/lib/perl5/site_perl/smbldap_conf.pm ]; +then + rm -f /usr/lib/perl5/site_perl/smbldap_conf.pm +fi chgrp 512 %{prefix}/sbin/smbldap-useradd.pl %{prefix}/sbin/smbldap_conf.pm || echo "An error occured while changing groups of smbldap-useradd.pl and smbldap_conf.pm in /usr/local/sbin. For proper operations, please ensure that they have the same posix group as the Samba domain administrator if there's a local Samba PDC." perl -i -pe 's/_SLAVELDAP_/localhost/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_MASTERLDAP_/localhost/' %{prefix}/sbin/smbldap_conf.pm @@ -101,11 +111,11 @@ perl -i -pe 's/_USERS_/Users/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_COMPUTERS_/Computers/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_GROUPS_/Groups/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_LOGINSHELL_/\/bin\/bash/' %{prefix}/sbin/smbldap_conf.pm -perl -i -pe 's/_HOMEPREFIX_/\/home\//' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_HOMEPREFIX_/\/home/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_BINDDN_/cn=Manager,\$suffix/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_BINDPW_/secret/' %{prefix}/sbin/smbldap_conf.pm perl -i -pe 's/_PDCNAME_/PDC-SRV/' %{prefix}/sbin/smbldap_conf.pm -perl -i -pe 's/_HOMEDRIVE_/H/' %{prefix}/sbin/smbldap_conf.pm +perl -i -pe 's/_HOMEDRIVE_/H:/' %{prefix}/sbin/smbldap_conf.pm # FIXME: links should not be removed on upgrade #%postun @@ -118,53 +128,13 @@ perl -i -pe 's/_HOMEDRIVE_/H/' %{prefix}/sbin/smbldap_conf.pm %defattr(-,root,root) %{prefix}/sbin/*.pl %{prefix}/sbin/smbldap_tools.pm -%config %{prefix}/sbin/smbldap_conf.pm +%config(noreplace) %{prefix}/sbin/smbldap_conf.pm %{prefix}/sbin/mkntpwd %doc /usr/share/doc/%{name}/ %changelog -* Fri Aug 22 2003 Jerome Tournier 0.8-1 -- support for Samba3.0 +* Fri Nov 28 2003 Jerome Tournier 0.8.2-1 +- new smb.conf file as example configuration file +- see Changelog file for updates in scripts -* Thu Sep 26 2002 Gérald Macinenti 0.7-2 -- top and account objectclasses replaced by InetOrgPerson - -* Sat Jun 1 2002 Olivier Lemaire 0.7-1 -- some bugfixes about smbldap-populate -- bugfixed the smbpasswd call in smbldap-useradd -- cleaned up the smbldap_conf -- more documentation - -* Tue Apr 30 2002 Brad Langhorst 0.6-2 -- changed requires samba-common to samba -- replaced /usr/local with %{prefix} to allow relocation - -* Tue Feb 5 2002 David Le Corfec 0.6-1 -- v0.6 - -* Mon Feb 4 2002 David Le Corfec 0.5-1 -- v0.5 - -* Mon Jan 14 2002 David Le Corfec 0.3-4 -- internal changes -- should upgrade smoothly from now on - -* Mon Jan 14 2002 David Le Corfec 0.2-1 -- added migration scripts - -* Fri Dec 28 2001 David Le Corfec 0.1-5 -- numeric group for chmod - -* Thu Dec 27 2001 David Le Corfec 0.1-4 -- misc bugfixes - -* Mon Dec 18 2001 David Le Corfec 0.1-3 -- changed files attrs for domain admins to add users -- added smbldap-populate.pl - -* Fri Dec 14 2001 David Le Corfec -- added mkntpwd - -* Wed Dec 12 2001 Olivier Lemaire -- Spec file was generated, and tested atomically. diff --git a/examples/LDAP/smbldap-tools/smbldap-useradd.pl b/examples/LDAP/smbldap-tools/smbldap-useradd.pl index a84d9f68b2..918bd4a4f6 100755 --- a/examples/LDAP/smbldap-tools/smbldap-useradd.pl +++ b/examples/LDAP/smbldap-tools/smbldap-useradd.pl @@ -35,102 +35,92 @@ use smbldap_conf; use Getopt::Std; my %Options; -my $ok = getopts('axnmwPG:u:g:d:s:c:k:A:B:C:D:E:F:H:N:S:?', \%Options); +my $ok = getopts('anmwPG:u:g:d:s:c:k:A:B:C:D:E:F:H:N:S:?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-awmugdsckGPABCDEFH?] username\n"; - print " -a is a Windows User (otherwise, Posix stuff only)\n"; - print " -w is a Windows Workstation (otherwise, Posix stuff only)\n"; - print " -x creates rid and primaryGroupID in hex instead of decimal\n"; - print " -u uid\n"; - print " -g gid\n"; - print " -G supplementary comma-separated groups\n"; - print " -n do not create a group\n"; - print " -d home\n"; - print " -s shell\n"; - print " -c gecos\n"; - print " -m creates home directory and copies /etc/skel\n"; - print " -k skeleton dir (with -m)\n"; - print " -P ends by invoking smbldap-passwd.pl\n"; - print " -A can change password ? 0 if no, 1 if yes\n"; - print " -B must change password ? 0 if no, 1 if yes\n"; - print " -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n"; - print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n"; - print " -E sambaLogonScript (DOS script to execute on login)\n"; - print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; - print " -H sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n"; - print " -N canonical name\n"; - print " -S surname\n"; - print " -? show this help message\n"; - exit (1); + print "Usage: $0 [-awmugdsckGPABCDEFH?] username\n"; + print " -a is a Windows User (otherwise, Posix stuff only)\n"; + print " -w is a Windows Workstation (otherwise, Posix stuff only)\n"; + print " -u uid\n"; + print " -g gid\n"; + print " -G supplementary comma-separated groups\n"; + print " -n do not create a group\n"; + print " -d home\n"; + print " -s shell\n"; + print " -c gecos\n"; + print " -m creates home directory and copies /etc/skel\n"; + print " -k skeleton dir (with -m)\n"; + print " -P ends by invoking smbldap-passwd.pl\n"; + print " -A can change password ? 0 if no, 1 if yes\n"; + print " -B must change password ? 0 if no, 1 if yes\n"; + print " -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n"; + print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n"; + print " -E sambaLogonScript (DOS script to execute on login)\n"; + print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; + print " -H sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n"; + print " -N canonical name\n"; + print " -S surname\n"; + print " -? show this help message\n"; + exit (1); } + # cause problems when dealing with getpwuid because of the # negative ttl and ldap modification my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; if ($nscd_status == 0) { - system "/etc/init.d/nscd stop > /dev/null 2>&1"; + system "/etc/init.d/nscd stop > /dev/null 2>&1"; } + # Read options my $userUidNumber = $Options{'u'}; if (!defined($userUidNumber)) { - # find first unused uid starting from $UID_START - while (defined(getpwuid($UID_START))) { - $UID_START++; - } - $userUidNumber = $UID_START; + # find first unused uid starting from $UID_START + while (defined(getpwuid($UID_START))) { + $UID_START++; + } + $userUidNumber = $UID_START; } elsif (getpwuid($userUidNumber)) { die "Uid already exists.\n"; } if ($nscd_status == 0) { - system "/etc/init.d/nscd start > /dev/null 2>&1"; + system "/etc/init.d/nscd start > /dev/null 2>&1"; } -# as rid we use 2 * uid + 1000 -my $userRid = 2 * $userUidNumber + 1000; -if (defined($Options{'x'})) { - $userRid= sprint("%x", $userRid); -} - my $createGroup = 0; my $userGidNumber = $Options{'g'}; # gid not specified ? if (!defined($userGidNumber)) { - # windows machine => $_defaultComputerGid - if (defined($Options{'w'})) { + # windows machine => $_defaultComputerGid + if (defined($Options{'w'})) { $userGidNumber = $_defaultComputerGid; -# } elsif (!defined($Options{'n'})) { + # } elsif (!defined($Options{'n'})) { # create new group (redhat style) # find first unused gid starting from $GID_START -# while (defined(getgrgid($GID_START))) { -# $GID_START++; -# } -# $userGidNumber = $GID_START; + # while (defined(getgrgid($GID_START))) { + # $GID_START++; + # } + # $userGidNumber = $GID_START; -# $createGroup = 1; + # $createGroup = 1; - } else { + } else { # user will have gid = $_defaultUserGid $userGidNumber = $_defaultUserGid; - } + } } else { - my $gid; - if (($gid = parse_group($userGidNumber)) < 0) { + my $gid; + if (($gid = parse_group($userGidNumber)) < 0) { print "$0: unknown group $userGidNumber\n"; exit (6); - } - $userGidNumber = $gid; + } + $userGidNumber = $gid; } -# as grouprid we use 2 * gid + 1001 -my $userGroupRid = 2 * $userGidNumber + 1001; -if (defined($Options{'x'})) { - $userGroupRid = sprint("%x", $userGroupRid); -} # Read only first @ARGV my $userName = $ARGV[0]; @@ -145,18 +135,49 @@ if ($userName =~ /^([\w -]+\$?)$/) { # user must not exist in LDAP (should it be nss-wide ?) my ($rc, $dn) = get_user_dn2($userName); if ($rc and defined($dn)) { - print "$0: user $userName exists\n"; - exit (9); + print "$0: user $userName exists\n"; + exit (9); } elsif (!$rc) { - print "$0: error in get_user_dn2\n"; - exit(10); + print "$0: error in get_user_dn2\n"; + exit(10); +} + +my $group_entry; +my $userGroupSID; +my $userRid; +if ($Options{'a'}) { + # as grouprid we use the value of the sambaSID attribute for + # group of gidNumber=$userGidNumber + $group_entry = read_group_entry_gid($userGidNumber); + $userGroupSID = $group_entry->get_value('sambaSID'); + unless ($userGroupSID) { + print "$0: unknown group SID not set for unix group $userGidNumber\n"; + print "check if your unix group is mapped to an NT group\n"; + exit (7); + } + + # as rid we use 2 * uid + 1000 + $userRid = 2 * $userUidNumber + 1000; + # let's test if this SID already exist + my $user_sid="$SID-$userRid"; + my $test_exist_sid=does_sid_exist($user_sid,$usersdn); + if ($test_exist_sid->count == 1) { + print "User SID already owned by\n"; + # there should not exist more than one entry, but ... + foreach my $entry ($test_exist_sid->all_entries) { + my $dn= $entry->dn; + chomp($dn); + print "$dn\n"; + } + exit(7); + } } my $userHomeDirectory; my ($userCN, $userSN); my $tmp; if (!defined($userHomeDirectory = $Options{'d'})) { - $userHomeDirectory = $_userHomePrefix."/".$userName; + $userHomeDirectory = $_userHomePrefix."/".$userName; } $_userLoginShell = $tmp if (defined($tmp = $Options{'s'})); $_userGecos = $tmp if (defined($tmp = $Options{'c'})); @@ -174,26 +195,26 @@ my $ldap_master=connect_ldap_master(); # MACHINE ACCOUNT if (defined($tmp = $Options{'w'})) { - # add a trailing dollar if missing - if ($userName =~ /[^\$]$/s) { + # add a trailing dollar if missing + if ($userName =~ /[^\$]$/s) { $userName .= "\$"; - } + } - #print "About to create machine $userName:\n"; + #print "About to create machine $userName:\n"; - if (!add_posix_machine ($userName, $userUidNumber, $userGidNumber)) { + if (!add_posix_machine ($userName, $userUidNumber, $userGidNumber)) { die "$0: error while adding posix account\n"; - } + } - if (!$with_smbpasswd) { + if (!$with_smbpasswd) { # (jtournier) - # Objectclass sambaSAMAccount is now added directly by samba when joigning the domain (for samba3) + # Objectclass sambaSamAccount is now added directly by samba when joigning the domain (for samba3) #if (!add_samba_machine_mkntpwd($userName, $userUidNumber)) { # die "$0: error while adding samba account\n"; #} - } else { + } else { if (!add_samba_machine($userName)) { - die "$0: error while adding samba account\n"; + die "$0: error while adding samba account\n"; } my $modify = $ldap_master->modify ( "$dn", changes => [ @@ -201,9 +222,9 @@ if (defined($tmp = $Options{'w'})) { ] ); $modify->code && warn "failed to modify entry: ", $modify->error ; - } + } - exit 0; + exit 0; } # USER ACCOUNT @@ -237,56 +258,62 @@ group_add_user($userGidNumber, $userName); my $grouplist; # adds to supplementary groups if (defined($grouplist = $Options{'G'})) { - add_grouplist_user($grouplist, $userName); + add_grouplist_user($grouplist, $userName); } # If user was created successfully then we should create his/her home dir if (defined($tmp = $Options{'m'})) { - unless ( $userName =~ /\$$/ ) { + unless ( $userName =~ /\$$/ ) { if ( !(-e $userHomeDirectory) ) { - system "mkdir $userHomeDirectory 2>/dev/null"; - system "cp -a $_skeletonDir/.[a-z,A-Z]* $_skeletonDir/* $userHomeDirectory 2>/dev/null"; - system "chown -R $userUidNumber:$userGidNumber $userHomeDirectory 2>/dev/null"; - system "chmod 700 $userHomeDirectory 2>/dev/null"; + system "mkdir $userHomeDirectory 2>/dev/null"; + system "cp -a $_skeletonDir/.[a-z,A-Z]* $_skeletonDir/* $userHomeDirectory 2>/dev/null"; + system "chown -R $userUidNumber:$userGidNumber $userHomeDirectory 2>/dev/null"; + system "chmod 700 $userHomeDirectory 2>/dev/null"; } - } + } } # Add Samba user infos if (defined($Options{'a'})) { - if (!$with_smbpasswd) { + if (!$with_smbpasswd) { my $winmagic = 2147483647; my $valpwdcanchange = 0; my $valpwdmustchange = $winmagic; + my $valpwdlastset = 0; my $valacctflags = "[UX]"; if (defined($tmp = $Options{'A'})) { - if ($tmp != 0) { + if ($tmp != 0) { $valpwdcanchange = "0"; - } else { + } else { $valpwdcanchange = "$winmagic"; - } + } } if (defined($tmp = $Options{'B'})) { - if ($tmp != 0) { + if ($tmp != 0) { $valpwdmustchange = "0"; - } else { + # To force a user to change his password: + # . the attribut sambaPwdLastSet must be != 0 + # . the attribut sambaAcctFlags must not match the 'X' flag + $valpwdlastset=$winmagic; + $valacctflags = "[U]"; + } else { $valpwdmustchange = "$winmagic"; - } + } } if (defined($tmp = $Options{'H'})) { - $valacctflags = "$tmp"; + $valacctflags = "$tmp"; } my $modify = $ldap_master->modify ( "uid=$userName,$usersdn", changes => [ - add => [objectClass => 'sambaSAMAccount'], - add => [sambaPwdLastSet => '0'], + add => [objectClass => 'sambaSamAccount'], + add => [sambaPwdLastSet => "$valpwdlastset"], add => [sambaLogonTime => '0'], add => [sambaLogoffTime => '2147483647'], add => [sambaKickoffTime => '2147483647'], @@ -300,7 +327,7 @@ if (defined($Options{'a'})) { $modify->code && die "failed to add entry: ", $modify->error ; - } else { + } else { my $FILE="|smbpasswd -s -a $userName >/dev/null" ; open (FILE, $FILE) || die "$!\n"; print FILE <modify ( "uid=$userName,$usersdn", changes => [ - add => [sambaPrimaryGroupSID => "$SID-$userGroupRid"], + add => [sambaPrimaryGroupSID => "$userGroupSID"], add => [sambaHomeDrive => "$valhomedrive"], - add => [sambaHomePath => "$valsmbhome"], - add => [sambaProfilePath => "$valprofilepath"], add => [sambaLogonScript => "$valscriptpath"], add => [sambaLMPassword => 'XXX'], add => [sambaNTPassword => 'XXX'] ] ); + $modify = $ldap_master->modify ( "uid=$userName,$usersdn", + 'replace' => { @mods } + ); + $modify->code && die "failed to add entry: ", $modify->error ; @@ -357,7 +403,7 @@ $ldap_master->unbind; # take down session if (defined($Options{'P'})) { - exec "/usr/local/sbin/smbldap-passwd.pl $userName" + exec "/usr/local/sbin/smbldap-passwd.pl $userName" } exit 0; @@ -366,57 +412,57 @@ exit 0; =head1 NAME - smbldap-useradd.pl - Create a new user or update default new - user information +smbldap-useradd.pl - Create a new user or update default new + user information =head1 SYNOPSIS - smbldap-useradd.pl [-c comment] [-d home_dir] - [-g initial_group] [-G group[,...]] - [-m [-k skeleton_dir]] - [-s shell] [-u uid [ -o]] [-P] - [-A canchange] [-B mustchange] [-C smbhome] - [-D homedrive] [-E scriptpath] [-F profilepath] - [-H acctflags] login +smbldap-useradd.pl [-c comment] [-d home_dir] + [-g initial_group] [-G group[,...]] + [-m [-k skeleton_dir]] + [-s shell] [-u uid [ -o]] [-P] + [-A canchange] [-B mustchange] [-C smbhome] + [-D homedrive] [-E scriptpath] [-F profilepath] + [-H acctflags] login =head1 DESCRIPTION - Creating New Users - The smbldap-useradd.pl command creates a new user account using - the values specified on the command line and the default - values from the system. - The new user account will be entered into the system - files as needed, the home directory will be created, and - initial files copied, depending on the command line options. +Creating New Users + The smbldap-useradd.pl command creates a new user account using + the values specified on the command line and the default + values from the system. + The new user account will be entered into the system + files as needed, the home directory will be created, and + initial files copied, depending on the command line options. - You have to use smbldap-passwd to set the user password. - For Samba users, rid is 2*uidNumber+1000, and primaryGroupID - is 2*gidNumber+1001. Thus you may want to use - smbldap-useradd.pl -a -g "Domain Admins" -u 500 Administrator - to create a sambaDomainName administrator (admin rid is 0x1F4 = 500 and - grouprid is 0x200 = 512) + You have to use smbldap-passwd to set the user password. + For Samba users, rid is 2*uidNumber+1000, and primaryGroupID + is 2*gidNumber+1001. Thus you may want to use + smbldap-useradd.pl -a -g "Domain Admins" -u 500 Administrator + to create a sambaDomainName administrator (admin rid is 0x1F4 = 500 and + grouprid is 0x200 = 512) - Without any option, the account created will be an Unix (Posix) - account. The following options may be used to add information: + Without any option, the account created will be an Unix (Posix) + account. The following options may be used to add information: - -a The user will have a Samba account (and Unix). +-a The user will have a Samba account (and Unix). - -w Creates an account for a Samba machine (Workstation), so that - it can join a sambaDomainName. + -w Creates an account for a Samba machine (Workstation), so that + it can join a sambaDomainName. - -x Creates rid and primaryGroupID in hex (for Samba 2.2.2 bug). Else - decimal (2.2.2 patched from cvs or 2.2.x, x > 2) + -x Creates rid and primaryGroupID in hex (for Samba 2.2.2 bug). Else + decimal (2.2.2 patched from cvs or 2.2.x, x > 2) - -c comment - The new user's comment field (gecos). + -c comment + The new user's comment field (gecos). -d home_dir The new user will be created using home_dir as the value for the user's login directory. The default is to append the login name - to default_home and use that as the login directory name. + to default_home and use that as the login directory name. - -g initial_group - The group name or number of the user's initial login group. The + -g initial_group + The group name or number of the user's initial login group. The group name must exist. A group number must refer to an already existing group. The default group number is 1. @@ -428,20 +474,20 @@ exit 0; is for the user to belong only to the initial group. -m The user's home directory will be created if it does not exist. - The files contained in skeleton_dir will be copied to the home - directory if the -k option is used, otherwise the files con­ - tained in /etc/skel will be used instead. Any directories con­ - tained in skeleton_dir or /etc/skel will be created in the - user's home directory as well. The -k option is only valid in + The files contained in skeleton_dir will be copied to the home + directory if the -k option is used, otherwise the files con­ + tained in /etc/skel will be used instead. Any directories con­ + tained in skeleton_dir or /etc/skel will be created in the + user's home directory as well. The -k option is only valid in conjunction with the -m option. The default is to not create the directory and to not copy any files. -s shell The name of the user's login shell. The default is to leave - this field blank, which causes the system to select the default - login shell. + this field blank, which causes the system to select the default + login shell. - -u uid The numerical value of the user's ID. This value must be + -u uid The numerical value of the user's ID. This value must be unique, unless the -o option is used. The value must be non- negative. The default is to use the smallest ID value greater than 1000 and greater than every other user. diff --git a/examples/LDAP/smbldap-tools/smbldap-userdel.pl b/examples/LDAP/smbldap-tools/smbldap-userdel.pl index 1a1a3214b5..f1e69e209c 100755 --- a/examples/LDAP/smbldap-tools/smbldap-userdel.pl +++ b/examples/LDAP/smbldap-tools/smbldap-userdel.pl @@ -37,9 +37,9 @@ my %Options; my $ok = getopts('r?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-r?] username\n"; - print " -r remove home directory\n"; - exit (1); + print "Usage: $0 [-r?] username\n"; + print " -r remove home directory\n"; + exit (1); } # Read only first @ARGV @@ -48,34 +48,34 @@ my $user = $ARGV[0]; my $dn; # user must not exist in LDAP if (!defined($dn=get_user_dn($user))) { - print "$0: user $user does not exist\n"; - exit (6); + print "$0: user $user does not exist\n"; + exit (6); } if ($< != 0) { - print "You must be root to delete an user\n"; - exit (1); + print "You must be root to delete an user\n"; + exit (1); } my $homedir; if (defined($Options{'r'})) { - $homedir=get_homedir($user); + $homedir=get_homedir($user); } # remove user from groups my $groups = find_groups_of $user; -my @grplines = split(/\n/, $groups); +my @grplines = split(/\n/,$groups); my $grp; foreach $grp (@grplines) { - my $gname = ""; - if ( $grp =~ /dn: cn=([^,]+),/) { + my $gname = ""; + if ( $grp =~ /dn: cn=([^,]+),/) { $gname = $1; #print "xx $gname\n"; - } - if ($gname ne "") { + } + if ($gname ne "") { group_remove_member($gname, $user); - } + } } # XXX @@ -83,9 +83,9 @@ delete_user($user); # delete dir -- be sure that homeDir is not a strange value if (defined($Options{'r'})) { - if ($homedir !~ /^\/dev/ and $homedir !~ /^\/$/) { + if ($homedir !~ /^\/dev/ and $homedir !~ /^\/$/) { system "rm -rf $homedir"; - } + } } my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; diff --git a/examples/LDAP/smbldap-tools/smbldap-usermod.pl b/examples/LDAP/smbldap-tools/smbldap-usermod.pl index f25c730fc8..70151b7412 100755 --- a/examples/LDAP/smbldap-tools/smbldap-usermod.pl +++ b/examples/LDAP/smbldap-tools/smbldap-usermod.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). @@ -29,48 +29,48 @@ use lib "$RealBin/"; use smbldap_tools; use smbldap_conf; - ##################### use Getopt::Std; my %Options; my $nscd_status; -my $ok = getopts('A:B:C:D:E:F:H:IJN:S:xme:f:u:g:G:d:l:s:c:ok:?h', \%Options); +my $ok = getopts('A:B:C:D:E:F:H:IJN:S:Pame:f:u:g:G:d:l:s:c:ok:?h', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) || ($Options{'h'}) ) { print "Usage: $0 [-awmugdsckxABCDEFGHI?h] username\n"; print "Available options are:\n"; - print " -c gecos\n"; - print " -d home directory\n"; - #print " -m move home directory\n"; - #print " -f inactive days\n"; - print " -u uid\n"; - print " -o uid can be non unique\n"; - print " -g gid\n"; - print " -G supplementary groups (comma separated)\n"; - print " -l login name\n"; - print " -s shell\n"; + print " -c gecos\n"; + print " -d home directory\n"; + #print " -m move home directory\n"; + #print " -f inactive days\n"; + print " -u uid\n"; + print " -o uid can be non unique\n"; + print " -g gid\n"; + print " -G supplementary groups (comma separated)\n"; + print " -l login name\n"; + print " -s shell\n"; print " -N canonical name\n"; print " -S surname\n"; + print " -P ends by invoking smbldap-passwd.pl\n"; print " For samba users:\n"; + print " -a add sambaSamAccount objectclass\n"; print " -e expire date (\"YYYY-MM-DD HH:MM:SS\")\n"; - print " -x creates rid and primaryGroupID in hex instead of decimal (for Samba 2.2.2 unpatched only)\n"; - print " -A can change password ? 0 if no, 1 if yes\n"; - print " -B must change password ? 0 if no, 1 if yes\n"; - print " -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n"; - print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n"; - print " -E sambaLogonScript (DOS script to execute on login)\n"; - print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; - print " -H sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n"; - print " -I disable an user. Can't be used with -H or -J\n"; - print " -J enable an user. Can't be used with -H or -I\n"; + print " -A can change password ? 0 if no, 1 if yes\n"; + print " -B must change password ? 0 if no, 1 if yes\n"; + print " -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n"; + print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n"; + print " -E sambaLogonScript (DOS script to execute on login)\n"; + print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n"; + print " -H sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n"; + print " -I disable an user. Can't be used with -H or -J\n"; + print " -J enable an user. Can't be used with -H or -I\n"; print " -?|-h show this help message\n"; - exit (1); + exit (1); } if ($< != 0) { - print "You must be root to modify an user\n"; - exit (1); + print "You must be root to modify an user\n"; + exit (1); } # Read only first @ARGV @@ -79,13 +79,13 @@ my $user = $ARGV[0]; # Read user data my $user_entry = read_user_entry($user); if (!defined($user_entry)) { - print "$0: user $user doesn't exist\n"; - exit (1); + print "$0: user $user doesn't exist\n"; + exit (1); } my $samba = 0; if (grep ($_ =~ /^sambaSamAccount$/i, $user_entry->get_value('objectClass'))) { - $samba = 1; + $samba = 1; } # get the dn of the user @@ -93,64 +93,94 @@ my $dn= $user_entry->dn(); my $tmp; my @mods; +if (defined($tmp = $Options{'a'})) { + # Let's connect to the directory first + my $ldap_master=connect_ldap_master(); + my $winmagic = 2147483647; + my $valpwdcanchange = 0; + my $valpwdmustchange = $winmagic; + my $valpwdlastset = 0; + my $valacctflags = "[UX]"; + my $user_entry=read_user_entry($user); + my $uidNumber = $user_entry->get_value('uidNumber'); + my $userRid = 2 * $uidNumber + 1000; + # apply changes + my $modify = $ldap_master->modify ( "$dn", + changes => [ + add => [objectClass => 'sambaSamAccount'], + add => [sambaPwdLastSet => "$valpwdlastset"], + add => [sambaLogonTime => '0'], + add => [sambaLogoffTime => '2147483647'], + add => [sambaKickoffTime => '2147483647'], + add => [sambaPwdCanChange => "$valpwdcanchange"], + add => [sambaPwdMustChange => "$valpwdmustchange"], + add => [displayName => "$_userGecos"], + add => [sambaSID=> "$SID-$userRid"], + add => [sambaAcctFlags => "$valacctflags"], + ] + ); + $modify->code && warn "failed to modify entry: ", $modify->error ; +} # Process options my $changed_uid; my $_userUidNumber; my $_userRid; if (defined($tmp = $Options{'u'})) { - if (defined($Options{'o'})) { + if (defined($Options{'o'})) { $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; if ($nscd_status == 0) { - system "/etc/init.d/nscd stop > /dev/null 2>&1"; + system "/etc/init.d/nscd stop > /dev/null 2>&1"; } if (getpwuid($tmp)) { - if ($nscd_status == 0) { + if ($nscd_status == 0) { system "/etc/init.d/nscd start > /dev/null 2>&1"; - } + } - print "$0: uid number $tmp exists\n"; - exit (6); + print "$0: uid number $tmp exists\n"; + exit (6); } if ($nscd_status == 0) { - system "/etc/init.d/nscd start > /dev/null 2>&1"; + system "/etc/init.d/nscd start > /dev/null 2>&1"; } - } + } push(@mods, 'uidNumber', $tmp); - $_userUidNumber = $tmp; + $_userUidNumber = $tmp; if ($samba) { # as rid we use 2 * uid + 1000 my $_userRid = 2 * $_userUidNumber + 1000; if (defined($Options{'x'})) { - $_userRid= sprint("%x", $_userRid); + $_userRid= sprint("%x", $_userRid); } push(@mods, 'sambaSID', $SID.'-'.$_userRid); - } - $changed_uid = 1; + } + $changed_uid = 1; } my $changed_gid; my $_userGidNumber; -my $_userGroupRid; +my $_userGroupSID; if (defined($tmp = $Options{'g'})) { - $_userGidNumber = parse_group($tmp); - if ($_userGidNumber < 0) { + $_userGidNumber = parse_group($tmp); + if ($_userGidNumber < 0) { print "$0: group $tmp doesn't exist\n"; exit (6); - } + } push(@mods, 'gidNumber', $_userGidNumber); if ($samba) { -# as grouprid we use 2 * gid + 1001 - my $_userGroupRid = 2 * $_userGidNumber + 1001; - if (defined($Options{'x'})) { - $_userGroupRid = sprint("%x", $_userGroupRid); - } - push(@mods, 'sambaPrimaryGroupSid', $SID.'-'.$_userGroupRid); + # as grouprid we use the sambaSID attribute's value of the group + my $group_entry = read_group_entry_gid($_userGidNumber); + my $_userGroupSID = $group_entry->get_value('sambaSID'); + unless ($_userGroupSID) { + print "$0: unknown group SID not set for unix group $_userGidNumber\n"; + exit (7); } - $changed_gid = 1; + push(@mods, 'sambaPrimaryGroupSid', $_userGroupSID); + } + $changed_gid = 1; } if (defined($tmp = $Options{'s'})) { @@ -158,7 +188,7 @@ if (defined($tmp = $Options{'s'})) { } -if (defined($tmp = $Options{'c'})) { +if (defined($tmp = $Options{'c'})) { push(@mods, 'gecos' => $tmp, 'description' => $tmp); if ($samba == 1) { @@ -180,24 +210,24 @@ if (defined($tmp = $Options{'S'})) { if (defined($tmp = $Options{'G'})) { - # remove user from old groups - my $groups = find_groups_of $user; - my @grplines = split(/\n/, $groups); + # remove user from old groups + my $groups = find_groups_of $user; + my @grplines = split(/\n/,$groups); - my $grp; - foreach $grp (@grplines) { + my $grp; + foreach $grp (@grplines) { my $gname = ""; if ( $grp =~ /dn: cn=([^,]+),/) { - $gname = $1; - #print "xx $gname\n"; + $gname = $1; + #print "xx $gname\n"; } if ($gname ne "") { - group_remove_member($gname, $user); + group_remove_member($gname, $user); } - } + } - # add user to new groups - add_grouplist_user($tmp, $user); + # add user to new groups + add_grouplist_user($tmp, $user); } # @@ -212,7 +242,7 @@ if (defined($tmp = $Options{'G'})) { my $attr; my $winmagic = 2147483647; -my $samba = is_samba_user($user); +$samba = is_samba_user($user); if (defined($tmp = $Options{'e'})) { if ($samba == 1) { @@ -234,9 +264,9 @@ if (defined($tmp = $Options{'A'})) { $_sambaPwdCanChange=$winmagic; } push(@mods, 'sambaPwdCanChange' => $_sambaPwdCanChange); - } else { + } else { print "User $user is not a samba user\n"; - } + } } my $_sambaPwdMustChange; @@ -244,13 +274,31 @@ if (defined($tmp = $Options{'B'})) { if ($samba == 1) { if ($tmp != 0) { $_sambaPwdMustChange=0; + # To force a user to change his password: + # . the attribut sambaPwdLastSet must be != 0 + # . the attribut sambaAcctFlags must not match the 'X' flag + my $_sambaAcctFlags; + my $flags = $user_entry->get_value('sambaAcctFlags'); + if ( $flags =~ /X/ ) { + my $letters; + if ($flags =~ /(\w+)/) { + $letters = $1; + } + $letters =~ s/X//; + $_sambaAcctFlags="\[$letters\]"; + push(@mods, 'sambaAcctFlags' => $_sambaAcctFlags); + } + my $_sambaPwdLastSet = $user_entry->get_value('sambaPwdLastSet'); + if ($_sambaPwdLastSet == 0) { + push(@mods, 'sambaPwdLastSet' => $winmagic); + } } else { $_sambaPwdMustChange=$winmagic; } push(@mods, 'sambaPwdMustChange' => $_sambaPwdMustChange); - } else { + } else { print "User $user is not a samba user\n"; - } + } } if (defined($tmp = $Options{'C'})) { @@ -292,7 +340,7 @@ if (defined($tmp = $Options{'F'})) { if ($samba == 1 and (defined $Options{'H'} or defined $Options{'I'} or defined $Options{'J'})) { my $_sambaAcctFlags; -if (defined($tmp = $Options{'H'})) { + if (defined($tmp = $Options{'H'})) { #$tmp =~ s/\\/\\\\/g; $_sambaAcctFlags=$tmp; } else { @@ -301,24 +349,24 @@ if (defined($tmp = $Options{'H'})) { $flags = $user_entry->get_value('sambaAcctFlags'); if (defined($tmp = $Options{'I'})) { - if ( !($flags =~ /D/) ) { - my $letters; - if ($flags =~ /(\w+)/) { - $letters = $1; - } + if ( !($flags =~ /D/) ) { + my $letters; + if ($flags =~ /(\w+)/) { + $letters = $1; + } $_sambaAcctFlags="\[D$letters\]"; - } -} elsif (defined($tmp = $Options{'J'})) { - if ( $flags =~ /D/ ) { - my $letters; - if ($flags =~ /(\w+)/) { - $letters = $1; - } - $letters =~ s/D//; + } + } elsif (defined($tmp = $Options{'J'})) { + if ( $flags =~ /D/ ) { + my $letters; + if ($flags =~ /(\w+)/) { + $letters = $1; + } + $letters =~ s/D//; $_sambaAcctFlags="\[$letters\]"; } - } -} + } + } if ("$_sambaAcctFlags" ne '') { @@ -344,7 +392,11 @@ $ldap_master->unbind; $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; if ($nscd_status == 0) { - system "/etc/init.d/nscd restart > /dev/null 2>&1"; + system "/etc/init.d/nscd restart > /dev/null 2>&1"; +} + +if (defined($Options{'P'})) { + exec "/usr/local/sbin/smbldap-passwd.pl $user" } @@ -352,32 +404,32 @@ if ($nscd_status == 0) { =head1 NAME - smbldap-usermod.pl - Modify a user account +smbldap-usermod.pl - Modify a user account =head1 SYNOPSIS - smbldap-usermod.pl [-c comment] [-d home_dir] - [-g initial_group] [-G group[,...]] - [-l login_name] [-p passwd] - [-s shell] [-u uid [ -o]] [-x] - [-A canchange] [-B mustchange] [-C smbhome] - [-D homedrive] [-E scriptpath] [-F profilepath] - [-H acctflags] login +smbldap-usermod.pl [-c comment] [-d home_dir] + [-g initial_group] [-G group[,...]] + [-l login_name] [-p passwd] + [-s shell] [-u uid [ -o]] [-x] + [-A canchange] [-B mustchange] [-C smbhome] + [-D homedrive] [-E scriptpath] [-F profilepath] + [-H acctflags] login =head1 DESCRIPTION - The smbldap-usermod.pl command modifies the system account files - to reflect the changes that are specified on the command line. - The options which apply to the usermod command are +The smbldap-usermod.pl command modifies the system account files + to reflect the changes that are specified on the command line. + The options which apply to the usermod command are - -c comment - The new value of the user's comment field (gecos). + -c comment + The new value of the user's comment field (gecos). -d home_dir The user's new login directory. - -g initial_group - The group name or number of the user's new initial login group. + -g initial_group + The group name or number of the user's new initial login group. The group name must exist. A group number must refer to an already existing group. The default group number is 1. @@ -391,18 +443,18 @@ if ($nscd_status == 0) { -l login_name The name of the user will be changed from login to login_name. - Nothing else is changed. In particular, the user's home direc­ - tory name should probably be changed to reflect the new login - name. + Nothing else is changed. In particular, the user's home direc­ + tory name should probably be changed to reflect the new login + name. - -s shell - The name of the user's new login shell. Setting this field to + -s shell + The name of the user's new login shell. Setting this field to blank causes the system to select the default login shell. -u uid The numerical value of the user's ID. This value must be - unique, unless the -o option is used. The value must be non- - negative. Any files which the user owns and which are - located in the directory tree rooted at the user's home direc­ + unique, unless the -o option is used. The value must be non- + negative. Any files which the user owns and which are + located in the directory tree rooted at the user's home direc­ tory will have the file user ID changed automatically. Files outside of the user's home directory must be altered manually. diff --git a/examples/LDAP/smbldap-tools/smbldap-usershow.pl b/examples/LDAP/smbldap-tools/smbldap-usershow.pl index 555b35ffd8..173480d76c 100755 --- a/examples/LDAP/smbldap-tools/smbldap-usershow.pl +++ b/examples/LDAP/smbldap-tools/smbldap-usershow.pl @@ -34,8 +34,8 @@ my %Options; my $ok = getopts('?', \%Options); if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) { - print "Usage: $0 [-?] username\n"; - print " -? show this help message\n"; + print "Usage: $0 [-?] username\n"; + print " -? show this help message\n"; exit (1); } diff --git a/examples/LDAP/smbldap-tools/smbldap_conf.pm b/examples/LDAP/smbldap-tools/smbldap_conf.pm index c3d5c1732c..257c205a2c 100644 --- a/examples/LDAP/smbldap-tools/smbldap_conf.pm +++ b/examples/LDAP/smbldap-tools/smbldap_conf.pm @@ -28,33 +28,33 @@ package smbldap_conf; # . be the configuration file for all smbldap-tools scripts use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS -$UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP -$slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd -$ldap_path $ldap_opts $ldapmodify $suffix $usersdn $computersdn -$groupsdn $scope $binddn $bindpasswd -$slaveDN $slavePw $masterDN $masterPw -$_userLoginShell $_userHomePrefix $_userGecos -$_defaultUserGid $_defaultComputerGid -$_skeletonDir $_userSmbHome -$_userProfile $_userHomeDrive -$_userScript $usersou $computersou $groupsou $SID $hash_encrypt -); + $UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP + $slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd + $ldap_path $ldap_opts $ldapmodify $suffix $usersdn $computersdn + $groupsdn $scope $binddn $bindpasswd + $slaveDN $slavePw $masterDN $masterPw + $_userLoginShell $_userHomePrefix $_userGecos + $_defaultUserGid $_defaultComputerGid + $_skeletonDir $_userSmbHome + $_userProfile $_userHomeDrive + $_userScript $usersou $computersou $groupsou $SID $hash_encrypt $_defaultMaxPasswordAge + ); use Exporter; $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = qw( -$UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP -$slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd -$ldap_path $ldap_opts $ldapmodify $suffix $usersdn -$computersdn $groupsdn $scope $binddn $bindpasswd -$slaveDN $slavePw $masterDN $masterPw -$_userLoginShell $_userHomePrefix $_userGecos -$_defaultUserGid $_defaultComputerGid $_skeletonDir -$_userSmbHome $_userProfile $_userHomeDrive $_userScript -$usersou $computersou $groupsou $SID $hash_encrypt -); + $UID_START $GID_START $smbpasswd $slaveLDAP $masterLDAP + $slavePort $masterPort $ldapSSL $slaveURI $masterURI $with_smbpasswd $mk_ntpasswd + $ldap_path $ldap_opts $ldapmodify $suffix $usersdn + $computersdn $groupsdn $scope $binddn $bindpasswd + $slaveDN $slavePw $masterDN $masterPw + $_userLoginShell $_userHomePrefix $_userGecos + $_defaultUserGid $_defaultComputerGid $_skeletonDir + $_userSmbHome $_userProfile $_userHomeDrive $_userScript + $usersou $computersou $groupsou $SID $hash_encrypt $_defaultMaxPasswordAge + ); ############################################################################## @@ -101,7 +101,7 @@ $ldapSSL = "0"; # LDAP Suffix # Ex: $suffix = "dc=IDEALX,dc=ORG"; -$suffix = "dc=IDEALX,dc=ORG"; +$suffix = "dc=IDEALX,dc=COM"; # Where are stored Users @@ -156,7 +156,7 @@ $masterPw = $bindpasswd; $_userLoginShell = q(_LOGINSHELL_); # Home directory prefix (without username) -#Ex: $_userHomePrefix = q(/home/); +# Ex: $_userHomePrefix = q(/home/); $_userHomePrefix = q(_HOMEPREFIX_); # Gecos @@ -171,6 +171,11 @@ $_defaultComputerGid = 553; # Skel dir $_skeletonDir = q(/etc/skel); +# Default password validation time (time in days) Comment the next line if +# you don't want password to be enable for $_defaultMaxPasswordAge days (be +# careful to the sambaPwdMustChange attribute's value) +$_defaultMaxPasswordAge = 45; + ############################################################################## # # SAMBA Configuration @@ -180,11 +185,15 @@ $_skeletonDir = q(/etc/skel); # The UNC path to home drives location without the username last extension # (will be dynamically prepended) # Ex: q(\\\\My-PDC-netbios-name\\homes) for \\My-PDC-netbios-name\homes +# Just comment this if you want to use the smb.conf 'logon home' directive +# and/or desabling roaming profiles $_userSmbHome = q(\\\\_PDCNAME_\\homes); # The UNC path to profiles locations without the username last extension # (will be dynamically prepended) # Ex: q(\\\\My-PDC-netbios-name\\profiles\\) for \\My-PDC-netbios-name\profiles +# Just comment this if you want to use the smb.conf 'logon path' directive +# and/or desabling roaming profiles $_userProfile = q(\\\\_PDCNAME_\\profiles\\); # The default Home Drive Letter mapping @@ -194,7 +203,7 @@ $_userHomeDrive = q(_HOMEDRIVE_); # The default user netlogon script name # if not used, will be automatically username.cmd -#$_userScript = q(startup.cmd); # make sure script file is edited under dos +# $_userScript = q(startup.cmd); # make sure script file is edited under dos ############################################################################## @@ -211,13 +220,13 @@ $mk_ntpasswd = "/usr/local/sbin/mkntpwd"; # those next externals commands are kept fot the migration scripts and # for the populate script: this will be updated as soon as possible - $slaveURI = "ldap://$slaveLDAP:$slavePort"; - $masterURI = "ldap://$masterLDAP:$masterPort"; +$slaveURI = "ldap://$slaveLDAP:$slavePort"; +$masterURI = "ldap://$masterLDAP:$masterPort"; $ldap_path = "/usr/bin"; if ( $ldapSSL eq "0" ) { -$ldap_opts = "-x"; + $ldap_opts = "-x"; } elsif ( $ldapSSL eq "1" ) { $ldap_opts = "-x -Z"; } else { diff --git a/examples/LDAP/smbldap-tools/smbldap_tools.pm b/examples/LDAP/smbldap-tools/smbldap_tools.pm index 8001442fe8..d33a65b7d1 100755 --- a/examples/LDAP/smbldap-tools/smbldap_tools.pm +++ b/examples/LDAP/smbldap-tools/smbldap_tools.pm @@ -34,36 +34,40 @@ $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = qw( -get_user_dn -get_group_dn + get_user_dn + get_group_dn is_group_member -is_samba_user + is_samba_user is_unix_user -is_user_valid -get_dn_from_line -add_posix_machine -add_samba_machine -add_samba_machine_mkntpwd -group_add_user -add_grouplist_user -disable_user -delete_user -group_add + is_user_valid + does_sid_exist + get_dn_from_line + add_posix_machine + add_samba_machine + add_samba_machine_mkntpwd + group_add_user + add_grouplist_user + disable_user + delete_user + group_add group_del -get_homedir -read_user + get_homedir + read_user read_user_entry -read_group -find_groups_of -parse_group -group_remove_member -group_get_members -do_ldapadd -do_ldapmodify -get_user_dn2 + read_group + read_group_entry + read_group_entry_gid + find_groups_of + parse_group + group_remove_member + group_get_members + do_ldapadd + do_ldapmodify + get_user_dn2 connect_ldap_master connect_ldap_slave -); + group_type_by_name + ); sub connect_ldap_master { @@ -116,14 +120,14 @@ sub connect_ldap_slave } sub get_user_dn -{ + { my $user = shift; my $dn=''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( base => $suffix, - scope => $scope, - filter => "(&(objectclass=posixAccount)(uid=$user))" - ); + scope => $scope, + filter => "(&(objectclass=posixAccount)(uid=$user))" + ); $mesg->code && die $mesg->error; foreach my $entry ($mesg->all_entries) { $dn= $entry->dn; @@ -131,70 +135,70 @@ sub get_user_dn $ldap_slave->unbind; chomp($dn); if ($dn eq '') { - return undef; + return undef; } $dn="dn: ".$dn; return $dn; -} + } sub get_user_dn2 -{ + { my $user = shift; my $dn=''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( base => $suffix, - scope => $scope, - filter => "(&(objectclass=posixAccount)(uid=$user))" - ); + scope => $scope, + filter => "(&(objectclass=posixAccount)(uid=$user))" + ); $mesg->code && warn "failed to perform search; ", $mesg->error; foreach my $entry ($mesg->all_entries) { - $dn= $entry->dn; + $dn= $entry->dn; } $ldap_slave->unbind; chomp($dn); if ($dn eq '') { - return (1,undef); + return (1,undef); } $dn="dn: ".$dn; return (1,$dn); -} + } sub get_group_dn { - my $group = shift; - my $dn=''; + my $group = shift; + my $dn=''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( base => $groupsdn, - scope => $scope, - filter => "(&(objectclass=posixGroup)(|(cn=$group)(gidNumber=$group)))" - ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries) { + scope => $scope, + filter => "(&(objectclass=posixGroup)(|(cn=$group)(gidNumber=$group)))" + ); + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { $dn= $entry->dn; } $ldap_slave->unbind; - chomp($dn); - if ($dn eq '') { + chomp($dn); + if ($dn eq '') { return undef; - } - $dn="dn: ".$dn; - return $dn; + } + $dn="dn: ".$dn; + return $dn; } # return (success, dn) # bool = is_samba_user($username) sub is_samba_user { - my $user = shift; + my $user = shift; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( base => $suffix, - scope => $scope, - filter => "(&(objectClass=sambaSamAccount)(uid=$user))" - ); - $mesg->code && die $mesg->error; + scope => $scope, + filter => "(&(objectClass=sambaSamAccount)(uid=$user))" + ); + $mesg->code && die $mesg->error; $ldap_slave->unbind; return ($mesg->count ne 0); } @@ -217,52 +221,68 @@ sub is_group_member my $dn_group = shift; my $user = shift; my $ldap_slave=connect_ldap_slave(); - my $mesg = $ldap_slave->search ( - base => "$dn_group", + my $mesg = $ldap_slave->search ( base => $dn_group, scope => 'base', filter => "(&(memberUid=$user))" ); $mesg->code && die $mesg->error; $ldap_slave->unbind; - return ($mesg->count ne 0); + return ($mesg->count ne 0); } +# all entries = does_sid_exist($sid,$scope) +sub does_sid_exist + { + my $sid = shift; + my $dn_group=shift; + my $ldap_slave=connect_ldap_slave(); + my $mesg = $ldap_slave->search ( base => $dn_group, + scope => $scope, + filter => "(sambaSID=$sid)" + #filter => "(&(objectClass=sambaSamAccount|objectClass=sambaGroupMapping)(sambaSID=$sid))" + ); + $mesg->code && die $mesg->error; + $ldap_slave->unbind; + return ($mesg); + } # try to bind with user dn and password to validate current password sub is_user_valid { - my ($user, $dn, $pass) = @_; - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - my $mesg= $ldap->bind (dn => $dn, password => $pass ); + my ($user, $dn, $pass) = @_; + my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; + my $mesg= $ldap->bind (dn => $dn, password => $pass ); if ($mesg->code eq 0) { - $ldap->unbind; - return 1; + $ldap->unbind; + return 1; } else { - if($ldap->bind()) { + if ($ldap->bind()) { $ldap->unbind; return 0; - } else { + } else { print ("The LDAP directory is not available.\n Check the server, cables ..."); $ldap->unbind; return 0; } die "Problem : contact your administrator"; } -} + } + # dn = get_dn_from_line ($dn_line) # helper to get "a=b,c=d" from "dn: a=b,c=d" sub get_dn_from_line { - my $dn = shift; - $dn =~ s/^dn: //; - return $dn; + my $dn = shift; + $dn =~ s/^dn: //; + return $dn; } + # success = add_posix_machine($user, $uid, $gid) sub add_posix_machine { - my ($user, $uid, $gid) = @_; + my ($user, $uid, $gid) = @_; # bind to a directory with dn and password my $ldap_master=connect_ldap_master(); my $add = $ldap_master->add ( "uid=$user,$computersdn", @@ -288,32 +308,32 @@ sub add_posix_machine # success = add_samba_machine($computername) sub add_samba_machine -{ + { my $user = shift; system "smbpasswd -a -m $user"; return 1; -} + } sub add_samba_machine_mkntpwd { - my ($user, $uid) = @_; - my $sambaSID = 2 * $uid + 1000; - my $name = $user; - $name =~ s/.$//s; + my ($user, $uid) = @_; + my $sambaSID = 2 * $uid + 1000; + my $name = $user; + $name =~ s/.$//s; - if ($mk_ntpasswd eq '') { + if ($mk_ntpasswd eq '') { print "Either set \$with_smbpasswd = 1 or specify \$mk_ntpasswd\n"; return 0; - } + } - my $ntpwd = `$mk_ntpasswd '$name'`; - chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':'))); - chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1)); + my $ntpwd = `$mk_ntpasswd '$name'`; + chomp(my $lmpassword = substr($ntpwd, 0, index($ntpwd, ':'))); + chomp(my $ntpassword = substr($ntpwd, index($ntpwd, ':')+1)); my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->modify ( "uid=$user,$computersdn", changes => [ - replace => [objectClass => ['inetOrgPerson', 'posixAccount', 'sambaSAMAccount']], + replace => [objectClass => ['inetOrgPerson', 'posixAccount', 'sambaSamAccount']], add => [sambaPwdLastSet => '0'], add => [sambaLogonTime => '0'], add => [sambaLogoffTime => '2147483647'], @@ -330,7 +350,7 @@ sub add_samba_machine_mkntpwd $modify->code && die "failed to add entry: ", $modify->error ; - return 1; + return 1; # take down the session $ldap_master->unbind; @@ -339,16 +359,16 @@ sub add_samba_machine_mkntpwd sub group_add_user { - my ($group, $userid) = @_; - my $members=''; - my $dn_line = get_group_dn($group); + my ($group, $userid) = @_; + my $members=''; + my $dn_line = get_group_dn($group); if (!defined(get_group_dn($group))) { print "$0: group \"$group\" doesn't exist\n"; exit (6); } - if (!defined($dn_line)) { + if (!defined($dn_line)) { return 1; - } + } my $dn = get_dn_from_line("$dn_line"); # on look if the user is already present in the group my $is_member=is_group_member($dn,$userid); @@ -367,8 +387,8 @@ sub group_add_user $modify->code && die "failed to modify entry: ", $modify->error ; # take down session $ldap_master->unbind; - } - } + } + } sub group_del { @@ -383,23 +403,23 @@ sub group_del sub add_grouplist_user { - my ($grouplist, $user) = @_; - my @array = split(/,/, $grouplist); - foreach my $group (@array) { + my ($grouplist, $user) = @_; + my @array = split(/,/, $grouplist); + foreach my $group (@array) { group_add_user($group, $user); - } + } } sub disable_user { - my $user = shift; - my $dn_line; + my $user = shift; + my $dn_line; my $dn = get_dn_from_line($dn_line); - - if (!defined($dn_line = get_user_dn($user))) { + + if (!defined($dn_line = get_user_dn($user))) { print "$0: user $user doesn't exist\n"; exit (10); - } + } my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->modify ( "$dn", changes => [ @@ -408,14 +428,14 @@ sub disable_user ); $modify->code && die "failed to modify entry: ", $modify->error ; - if (is_samba_user($user)) { + if (is_samba_user($user)) { my $modify = $ldap_master->modify ( "$dn", changes => [ replace => [sambaAcctFlags => '[D ]'] ] ); $modify->code && die "failed to modify entry: ", $modify->error ; - } + } # take down session $ldap_master->unbind; } @@ -423,43 +443,43 @@ sub disable_user # delete_user($user) sub delete_user { - my $user = shift; - my $dn_line; + my $user = shift; + my $dn_line; - if (!defined($dn_line = get_user_dn($user))) { + if (!defined($dn_line = get_user_dn($user))) { print "$0: user $user doesn't exist\n"; exit (10); - } + } - my $dn = get_dn_from_line($dn_line); + my $dn = get_dn_from_line($dn_line); my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->delete($dn); $ldap_master->unbind; } -# $success = group_add($groupname, $group_gid, $force_using_existing_gid) +# $gid = group_add($groupname, $group_gid, $force_using_existing_gid) sub group_add { - my ($gname, $gid, $force) = @_; - my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; - if ($nscd_status == 0) { + my ($gname, $gid, $force) = @_; + my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1"; + if ($nscd_status == 0) { system "/etc/init.d/nscd stop > /dev/null 2>&1"; - } - if (!defined($gid)) { + } + if (!defined($gid)) { while (defined(getgrgid($GID_START))) { - $GID_START++; + $GID_START++; } $gid = $GID_START; - } else { + } else { if (!defined($force)) { - if (defined(getgrgid($gid))) { - return 0; - } + if (defined(getgrgid($gid))) { + return undef; + } } - } - if ($nscd_status == 0) { + } + if ($nscd_status == 0) { system "/etc/init.d/nscd start > /dev/null 2>&1"; - } + } my $ldap_master=connect_ldap_master(); my $modify = $ldap_master->add ( "cn=$gname,$groupsdn", attrs => [ @@ -472,67 +492,67 @@ sub group_add $modify->code && die "failed to add entry: ", $modify->error ; # take down session $ldap_master->unbind; - return 1; + return $gid; } # $homedir = get_homedir ($user) sub get_homedir { - my $user = shift; - my $homeDir=''; + my $user = shift; + my $homeDir=''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( base =>$suffix, scope => $scope, filter => "(&(objectclass=posixAccount)(uid=$user))" ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries){ + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { foreach my $attr ($entry->attributes) { - if ($attr=~/\bhomeDirectory\b/){ - foreach my $ent($entry->get_value($attr)) { + if ($attr=~/\bhomeDirectory\b/) { + foreach my $ent ($entry->get_value($attr)) { $homeDir.= $attr.": ".$ent."\n"; - } + } } - } - } + } + } $ldap_slave->unbind; - chomp $homeDir; - if ($homeDir eq '') { + chomp $homeDir; + if ($homeDir eq '') { return undef; - } - $homeDir =~ s/^homeDirectory: //; - return $homeDir; + } + $homeDir =~ s/^homeDirectory: //; + return $homeDir; } # search for an user sub read_user { - my $user = shift; - my $lines =''; + my $user = shift; + my $lines =''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( # perform a search - base => $suffix, - scope => $scope, - filter => "(&(objectclass=posixAccount)(uid=$user))" - ); + base => $suffix, + scope => $scope, + filter => "(&(objectclass=posixAccount)(uid=$user))" + ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries) { + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { $lines.= "dn: " . $entry->dn."\n"; foreach my $attr ($entry->attributes) { - { + { $lines.= $attr.": ".join(',', $entry->get_value($attr))."\n"; - } + } } - } + } # take down session $ldap_slave->unbind; - chomp $lines; - if ($lines eq '') { + chomp $lines; + if ($lines eq '') { return undef; - } - return $lines; + } + return $lines; } # search for a user @@ -556,86 +576,124 @@ sub read_user_entry # search for a group sub read_group { - my $user = shift; - my $lines =''; + my $user = shift; + my $lines =''; my $ldap_slave=connect_ldap_slave(); my $mesg = $ldap_slave->search ( # perform a search - base => $groupsdn, - scope => $scope, - filter => "(&(objectclass=posixGroup)(cn=$user))" - ); + base => $groupsdn, + scope => $scope, + filter => "(&(objectclass=posixGroup)(cn=$user))" + ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries) { + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { $lines.= "dn: " . $entry->dn."\n"; foreach my $attr ($entry->attributes) { - { + { $lines.= $attr.": ".join(',', $entry->get_value($attr))."\n"; - } + } } - } + } # take down session $ldap_slave->unbind; - chomp $lines; - if ($lines eq '') { + chomp $lines; + if ($lines eq '') { return undef; - } - return $lines; + } + return $lines; } # find groups of a given user ##### MODIFIE ######## sub find_groups_of { - my $user = shift; - my $lines =''; + my $user = shift; + my $lines =''; my $ldap_slave=connect_ldap_slave; my $mesg = $ldap_slave->search ( # perform a search - base => $groupsdn, - scope => $scope, - filter => "(&(objectclass=posixGroup)(memberuid=$user))" - ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries) { + base => $groupsdn, + scope => $scope, + filter => "(&(objectclass=posixGroup)(memberuid=$user))" + ); + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { $lines.= "dn: ".$entry->dn."\n"; - } + } $ldap_slave->unbind; - chomp($lines); + chomp($lines); if ($lines eq '') { return undef; } - return $lines; + return $lines; + } + +sub read_group_entry { + my $group = shift; + my $entry; + my %res; + my $ldap_slave=connect_ldap_slave(); + my $mesg = $ldap_slave->search ( # perform a search + base => $groupsdn, + scope => $scope, + filter => "(&(objectclass=posixGroup)(cn=$group))" + ); + + $mesg->code && die $mesg->error; + my $nb=$mesg->count; + if ($nb > 1) { + print "Error: $nb groups exist \"cn=$group\"\n"; + foreach $entry ($mesg->all_entries) { my $dn=$entry->dn; print " $dn\n"; } + exit 11; + } else { + $entry = $mesg->shift_entry(); } + return $entry; +} + +sub read_group_entry_gid { + my $group = shift; + my %res; + my $ldap_slave=connect_ldap_slave(); + my $mesg = $ldap_slave->search ( # perform a search + base => $groupsdn, + scope => $scope, + filter => "(&(objectclass=posixGroup)(gidNumber=$group))" + ); + + $mesg->code && die $mesg->error; + my $entry = $mesg->shift_entry(); + return $entry; +} # return the gidnumber for a group given as name or gid # -1 : bad group name # -2 : bad gidnumber sub parse_group { - my $userGidNumber = shift; - if ($userGidNumber =~ /[^\d]/ ) { + my $userGidNumber = shift; + if ($userGidNumber =~ /[^\d]/ ) { my $gname = $userGidNumber; my $gidnum = getgrnam($gname); if ($gidnum !~ /\d+/) { - return -1; + return -1; } else { - $userGidNumber = $gidnum; + $userGidNumber = $gidnum; } - } elsif (!defined(getgrgid($userGidNumber))) { + } elsif (!defined(getgrgid($userGidNumber))) { return -2; - } - return $userGidNumber; + } + return $userGidNumber; } # remove $user from $group sub group_remove_member { - my ($group, $user) = @_; - my $members=''; - my $grp_line = get_group_dn($group); - if (!defined($grp_line)) { + my ($group, $user) = @_; + my $members=''; + my $grp_line = get_group_dn($group); + if (!defined($grp_line)) { return 0; - } + } my $dn = get_dn_from_line($grp_line); # we test if the user exist in the group my $is_member=is_group_member($dn,$user); @@ -646,40 +704,40 @@ sub group_remove_member changes => [ delete => [memberUid => ["$user"]] ] - ); + ); $modify->code && die "failed to delete entry: ", $modify->error ; $ldap_master->unbind; - } - return 1; + } + return 1; } sub group_get_members { - my ($group) = @_; - my $members; - my @resultat; - my $grp_line = get_group_dn($group); + my ($group) = @_; + my $members; + my @resultat; + my $grp_line = get_group_dn($group); if (!defined($grp_line)) { return 0; } - my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; - $ldap->bind ; + my $ldap = Net::LDAP->new($slaveLDAP) or die "erreur LDAP"; + $ldap->bind ; my $mesg = $ldap->search ( base => $groupsdn, - scope => $scope, - filter => "(&(objectclass=posixgroup)(cn=$group))" - ); - $mesg->code && die $mesg->error; - foreach my $entry ($mesg->all_entries){ - foreach my $attr ($entry->attributes){ - if ($attr=~/\bmemberUid\b/){ + scope => $scope, + filter => "(&(objectclass=posixgroup)(cn=$group))" + ); + $mesg->code && die $mesg->error; + foreach my $entry ($mesg->all_entries) { + foreach my $attr ($entry->attributes) { + if ($attr=~/\bmemberUid\b/) { foreach my $ent ($entry->get_value($attr)) { push (@resultat,$ent); - } + } + } } - } -} + } return @resultat; } @@ -697,5 +755,17 @@ EOF return $rc; } +sub group_type_by_name { + my $type_name = shift; + my %groupmap = ( + 'domain' => 2, + 'local' => 4, + 'builtin' => 5 + ); + return $groupmap{$type_name}; +} + + + 1; -- cgit From c93c925a2d563576b7e66f9c2adf41fd1e2a3174 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 6 Jan 2004 15:42:48 +0000 Subject: Correctly detect AFS headers on SuSE in /usr/include/afs/afs/ Volker (This used to be commit 9f0292091b37cac637ba86cab6c8fd1800faef5c) --- source3/configure.in | 52 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index c5cf9f1dbb..1121551efc 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2260,13 +2260,14 @@ AC_ARG_WITH(smbwrapper, ################################################# # check for AFS clear-text auth support +samba_cv_WITH_AFS=no AC_MSG_CHECKING(whether to use AFS clear-text auth) AC_ARG_WITH(afs, [ --with-afs Include AFS clear-text auth support (default=no) ], [ case "$withval" in - yes) - AC_MSG_RESULT(yes) - AC_DEFINE(WITH_AFS,1,[Whether to include AFS clear-text auth support]) + yes|auto) + AC_MSG_RESULT($withval) + samba_cv_WITH_AFS=$withval ;; *) AC_MSG_RESULT(no) @@ -2277,13 +2278,14 @@ AC_ARG_WITH(afs, #################################################### # check for Linux-specific AFS fake-kaserver support +samba_cv_WITH_FAKE_KASERVER=no AC_MSG_CHECKING(whether to use AFS fake-kaserver) AC_ARG_WITH(fake-kaserver, [ --with-fake-kaserver Include AFS fake-kaserver support (default=no) ], [ case "$withval" in - yes) - AC_MSG_RESULT(yes) - AC_DEFINE(WITH_FAKE_KASERVER,1,[Whether to include AFS fake-kaserver support]) + yes|auto) + AC_MSG_RESULT($withval) + samba_cv_WITH_FAKE_KASERVER=$withval ;; *) AC_MSG_RESULT(no) @@ -2292,6 +2294,44 @@ AC_ARG_WITH(fake-kaserver, AC_MSG_RESULT(no) ) +################################################# +# decide whether we can support WITH_AFS and / or WITH_FAKE_KASERVER +if test x"$samba_cv_WITH_AFS" != x"no" || + test x"$samba_cv_WITH_FAKE_KASERVER" != x"no"; then + + # see if this box has the afs-headers in /usr/include/afs + AC_MSG_CHECKING(for /usr/include/afs) + if test -d /usr/include/afs; then + CFLAGS="$CFLAGS -I/usr/include/afs" + CPPFLAGS="$CPPFLAGS -I/usr/include/afs" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + + # check for afs.h + have_afs_headers=no + AC_CHECK_HEADERS(afs.h afs/afs.h) + if test x"$ac_cv_header_afs_h" = x"no" && test x"$ac_cv_header_afs_afs_h" = x"no"; then + if test x"$samba_cv_WITH_FAKE_KASERVER" = x"auto" || + test x"$samba_cv_WITH_AFS" = x"auto"; then + AC_MSG_WARN([AFS cannot be supported without afs.h]) + else + AC_MSG_ERROR([AFS cannot be supported without afs.h]) + fi + else + have_afs_headers=yes + fi +fi + +if test x"$samba_cv_WITH_FAKE_KASERVER" != x"no" && test x"$have_afs_headers" == x"yes"; then + AC_DEFINE(WITH_FAKE_KASERVER,1,[Whether to include AFS fake-kaserver support]) +fi + +if test x"$samba_cv_WITH_AFS" != x"no" && test x"$have_afs_headers" = x"yes"; then + AC_DEFINE(WITH_AFS,1,[Whether to include AFS clear-text auth support]) +fi + ################################################# # check for the DFS clear-text auth system AC_MSG_CHECKING(whether to use DFS clear-text auth) -- cgit From ba97fc434ac233179633f6acd3b2cd56cb2b1f86 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 6 Jan 2004 18:26:53 +0000 Subject: isolate ldap debug messages to the common smbldap_XXX() functions (This used to be commit 4c877ccc16bcb69490c4d34d2ef5f727bf98438e) --- source3/lib/smbldap.c | 13 +++++++++---- source3/passdb/pdb_ldap.c | 3 --- source3/sam/idmap_ldap.c | 5 ----- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 2eeec156bd..1156bd6639 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -914,6 +914,9 @@ int smbldap_search(struct smbldap_state *ldap_state, char *utf8_filter; SMB_ASSERT(ldap_state); + + DEBUG(5,("smbldap_search: base => [%s], filter => [%s], scope => [%d]\n", + base, filter, scope)); if (ldap_state->last_rebind.tv_sec > 0) { struct timeval tval; @@ -970,6 +973,8 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at SMB_ASSERT(ldap_state); + DEBUG(5,("smbldap_modify: dn => [%s]\n", dn )); + if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) { return LDAP_NO_MEMORY; } @@ -1001,6 +1006,8 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs SMB_ASSERT(ldap_state); + DEBUG(5,("smbldap_add: dn => [%s]\n", dn )); + if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) { return LDAP_NO_MEMORY; } @@ -1032,6 +1039,8 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn) SMB_ASSERT(ldap_state); + DEBUG(5,("smbldap_delete: dn => [%s]\n", dn )); + if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) { return LDAP_NO_MEMORY; } @@ -1094,8 +1103,6 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter, int scope = LDAP_SCOPE_SUBTREE; int rc; - DEBUG(2, ("smbldap_search_suffix: searching for:[%s]\n", filter)); - rc = smbldap_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result); if (rc != LDAP_SUCCESS) { @@ -1104,8 +1111,6 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter, &ld_error); DEBUG(0,("smbldap_search_suffix: Problem during the LDAP search: %s (%s)\n", ld_error?ld_error:"(unknown)", ldap_err2string (rc))); - DEBUG(3,("smbldap_search_suffix: Query was: %s, %s\n", lp_ldap_suffix(), - filter)); SAFE_FREE(ld_error); } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 1f44f5ab60..6e8ff83507 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1639,9 +1639,6 @@ static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state, int rc; char **attr_list; - DEBUG(2, ("ldapsam_search_one_group: searching for:[%s]\n", filter)); - - attr_list = get_attr_list(groupmap_attr_list); rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix (), scope, diff --git a/source3/sam/idmap_ldap.c b/source3/sam/idmap_ldap.c index db1bb74de5..a2afd7d424 100644 --- a/source3/sam/idmap_ldap.c +++ b/source3/sam/idmap_ldap.c @@ -507,9 +507,6 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) LDAP_OBJ_IDMAP_ENTRY, type, ((id_type & ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid)); - - DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter )); - attr_list = get_attr_list( sidmap_attr_list ); rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result); @@ -580,8 +577,6 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si else type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ); - DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter)); - /* do the search and check for errors */ attr_list = get_attr_list( sidmap_attr_list ); -- cgit From a7d76e7cec64cc94021dcec7ddced56c960f2253 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 6 Jan 2004 19:57:50 +0000 Subject: remove unused seek_file(); don't hardcode '\' when printing the auth-user (This used to be commit 175c5c9faa8c1cb3577eb96598434e6097d408c7) --- source3/nsswitch/wbinfo.c | 2 +- source3/smbd/fileio.c | 25 ------------------------- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 792af84827..7d25524f8e 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -923,7 +923,7 @@ static void wbinfo_get_auth_user(void) /* Pretty print authorised user info */ - d_printf("%s%s%s%s%s\n", domain ? domain : "", domain ? "\\" : "", + d_printf("%s%s%s%s%s\n", domain ? domain : "", domain ? lp_winbind_separator(): "", user, password ? "%" : "", password ? password : ""); SAFE_FREE(user); diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index f395954d05..3462a3b9fa 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -24,31 +24,6 @@ static BOOL setup_write_cache(files_struct *, SMB_OFF_T); -/**************************************************************************** - Seek a file. Try to avoid the seek if possible. -****************************************************************************/ - -static SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) -{ - SMB_OFF_T seek_ret; - - seek_ret = SMB_VFS_LSEEK(fsp,fsp->fd,pos,SEEK_SET); - - if(seek_ret == -1) { - DEBUG(0,("seek_file: (%s) sys_lseek failed. Error was %s\n", - fsp->fsp_name, strerror(errno) )); - fsp->pos = -1; - return -1; - } - - fsp->pos = seek_ret; - - DEBUG(10,("seek_file (%s): requested pos = %.0f, new pos = %.0f\n", - fsp->fsp_name, (double)pos, (double)fsp->pos )); - - return(fsp->pos); -} - /**************************************************************************** Read from write cache if we can. ****************************************************************************/ -- cgit From 24cf387139aea9c4ba884eda6c3eb3597d5c12d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Jan 2004 22:34:04 +0000 Subject: Patch penguin. Cleaning out old mbp patch. Jeremy. (This used to be commit a0dc10bed68ef961609c0a4a456b6a132e2e347b) --- source3/smbd/chgpasswd.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 5caf78e41a..e6117245e7 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -343,7 +343,7 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass, /* allocate a pseudo-terminal device */ if ((master = findpty(&slavedev)) < 0) { - DEBUG(3, ("Cannot Allocate pty for password change: %s\n", pass->pw_name)); + DEBUG(3, ("chat_with_program: Cannot Allocate pty for password change: %s\n", pass->pw_name)); return (False); } @@ -355,7 +355,7 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass, CatchChildLeaveStatus(); if ((pid = sys_fork()) < 0) { - DEBUG(3, ("Cannot fork() child for password change: %s\n", pass->pw_name)); + DEBUG(3, ("chat_with_program: Cannot fork() child for password change: %s\n", pass->pw_name)); close(master); CatchChild(); return (False); @@ -364,7 +364,7 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass, /* we now have a pty */ if (pid > 0) { /* This is the parent process */ if ((chstat = talktochild(master, chatsequence)) == False) { - DEBUG(3, ("Child failed to change password: %s\n", pass->pw_name)); + DEBUG(3, ("chat_with_program: Child failed to change password: %s\n", pass->pw_name)); kill(pid, SIGKILL); /* be sure to end this process */ } @@ -377,7 +377,7 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass, } if (wpid < 0) { - DEBUG(3, ("The process is no longer waiting!\n\n")); + DEBUG(3, ("chat_with_program: The process is no longer waiting!\n\n")); close(master); CatchChild(); return (False); @@ -391,19 +391,21 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass, close(master); if (pid != wpid) { - DEBUG(3, ("We were waiting for the wrong process ID\n")); + DEBUG(3, ("chat_with_program: We were waiting for the wrong process ID\n")); return (False); } - if (WIFEXITED(wstat) == 0) { - DEBUG(3, ("The process exited while we were waiting\n")); + if (WIFEXITED(wstat) && (WEXITSTATUS(wstat) != 0)) { + DEBUG(3, ("chat_with_program: The process exited with status %d \ +while we were waiting\n", WEXITSTATUS(wstat))); return (False); } - if (WEXITSTATUS(wstat) != 0) { - DEBUG(3, ("The status of the process exiting was %d\n", - wstat)); +#if defined(WIFSIGNALLED) && defined(WTERMSIG) + else if (WIFSIGNALLED(wstat)) { + DEBUG(3, ("chat_with_program: The process was killed by signal %d \ +while we were waiting\n", WTERMSIG(wstat))); return (False); } - +#endif } else { /* CHILD */ @@ -418,7 +420,7 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass, if (as_root) become_root(); - DEBUG(3, ("Dochild for user %s (uid=%d,gid=%d) (as_root = %s)\n", pass->pw_name, + DEBUG(3, ("chat_with_program: Dochild for user %s (uid=%d,gid=%d) (as_root = %s)\n", pass->pw_name, (int)getuid(), (int)getgid(), BOOLSTR(as_root) )); chstat = dochild(master, slavedev, pass, passwordprogram, as_root); @@ -434,7 +436,7 @@ static BOOL chat_with_program(char *passwordprogram, struct passwd *pass, } if (chstat) - DEBUG(3, ("Password change %ssuccessful for user %s\n", + DEBUG(3, ("chat_with_program: Password change %ssuccessful for user %s\n", (chstat ? "" : "un"), pass->pw_name)); return (chstat); } @@ -449,12 +451,12 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL struct passwd *pass; if (!name) { - DEBUG(1, ("NULL username specfied to chgpasswd()!\n")); + DEBUG(1, ("chgpasswd: NULL username specfied !\n")); } pass = Get_Pwnam(name); if (!pass) { - DEBUG(1, ("Username does not exist in system passwd!\n")); + DEBUG(1, ("chgpasswd: Username does not exist in system !\n")); return False; } @@ -462,17 +464,17 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL oldpass = ""; } - DEBUG(3, ("Password change (as_root=%s) for user: %s\n", BOOLSTR(as_root), name)); + DEBUG(3, ("chgpasswd: Password change (as_root=%s) for user: %s\n", BOOLSTR(as_root), name)); #if DEBUG_PASSWORD - DEBUG(100, ("Passwords: old=%s new=%s\n", oldpass, newpass)); + DEBUG(100, ("chgpasswd: Passwords: old=%s new=%s\n", oldpass, newpass)); #endif /* Take the passed information and test it for minimum criteria */ /* Minimum password length */ if (strlen(newpass) < lp_min_passwd_length()) { /* too short, must be at least MINPASSWDLENGTH */ - DEBUG(0, ("Password Change: user %s, New password is shorter than minimum password length = %d\n", + DEBUG(0, ("chgpasswd: Password Change: user %s, New password is shorter than minimum password length = %d\n", name, lp_min_passwd_length())); return (False); /* inform the user */ } @@ -480,7 +482,7 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL /* Password is same as old password */ if (strcmp(oldpass, newpass) == 0) { /* don't allow same password */ - DEBUG(2, ("Password Change: %s, New password is same as old\n", name)); /* log the attempt */ + DEBUG(2, ("chgpasswd: Password Change: %s, New password is same as old\n", name)); /* log the attempt */ return (False); /* inform the user */ } @@ -492,7 +494,7 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL len = strlen(oldpass); for (i = 0; i < len; i++) { if (iscntrl((int)oldpass[i])) { - DEBUG(0, ("chat_with_program: oldpass contains control characters (disallowed).\n")); + DEBUG(0, ("chgpasswd: oldpass contains control characters (disallowed).\n")); return False; } } @@ -500,7 +502,7 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL len = strlen(newpass); for (i = 0; i < len; i++) { if (iscntrl((int)newpass[i])) { - DEBUG(0, ("chat_with_program: newpass contains control characters (disallowed).\n")); + DEBUG(0, ("chgpasswd: newpass contains control characters (disallowed).\n")); return False; } } @@ -570,7 +572,7 @@ the string %%u, and the given string %s does not.\n", passwordprogram )); BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL as_root) { - DEBUG(0, ("Password changing not compiled in (user=%s)\n", name)); + DEBUG(0, ("chgpasswd: Password changing not compiled in (user=%s)\n", name)); return (False); } #endif /* ALLOW_CHANGE_PASSWORD */ -- cgit From 0026f778bb6f8e3e0f84a907c8f3e337f4f43533 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 7 Jan 2004 00:06:45 +0000 Subject: (merge from 3.0) Fix segfualt caused by incorrect configuration. If lp_realm() was not set, but security=ADS, we would attempt to free the principal name that krb5 never allocated. Also fix the dump_data() of the session key, now that we use a data_blob to store that. Andrew Bartlett (This used to be commit 24d7eed6cae8015e020ad34c13130ee8afc9052e) --- source3/libads/kerberos_verify.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index b0efb8f598..50e6971815 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -173,8 +173,11 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, krb5_rcache rcache = NULL; int ret, i; krb5_keyblock *key = NULL; + krb5_principal host_princ; char *host_princ_s = NULL; + BOOL free_host_princ = False; + fstring myname; char *password_s = NULL; krb5_data password; @@ -239,6 +242,8 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, goto out; } + free_host_princ = True; + /* * JRA. We must set the rcache here. This will prevent replay attacks. */ @@ -339,10 +344,7 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, free(packet.data); get_krb5_smb_session_key(context, auth_context, session_key, True); -#ifdef DEBUG_PASSWORD - DEBUG(10,("SMB session key (from ticket) follows:\n")); - dump_data(10, session_key, 16); -#endif + dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length); #if 0 file_save("/tmp/ticket.dat", ticket->data, ticket->length); @@ -386,7 +388,9 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, if (!NT_STATUS_IS_OK(sret)) data_blob_free(ap_rep); - krb5_free_principal(context, host_princ); + if (free_host_princ) + krb5_free_principal(context, host_princ); + if (tkt != NULL) krb5_free_ticket(context, tkt); free_kerberos_etypes(context, enctypes); -- cgit From b54c4ccead0ecf2a9be6e7f48cc35b6e87194737 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 7 Jan 2004 10:02:42 +0000 Subject: Merge Translation fixes Volker (This used to be commit 70b0fcdeec4810944a4e0d9bbaf6a979b2fb914a) --- source3/po/de.msg | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/po/de.msg b/source3/po/de.msg index e2294d5087..b1b84a21b6 100644 --- a/source3/po/de.msg +++ b/source3/po/de.msg @@ -436,15 +436,15 @@ msgstr "" #: ../web/statuspage.c:368 msgid "Stop winbindd" -msgstr "Stopp nmbd" +msgstr "Stopp winbindd" #: ../web/statuspage.c:370 msgid "Start winbindd" -msgstr "Start nmbd" +msgstr "Start winbindd" #: ../web/statuspage.c:372 msgid "Restart winbindd" -msgstr "Neustart nmbd" +msgstr "Neustart winbindd" #. stop, restart all #: ../web/statuspage.c:381 @@ -453,12 +453,12 @@ msgstr "" #: ../web/statuspage.c:382 msgid "Restart All" -msgstr "Neustart nmbd" +msgstr "Neustart Alle" #. start all #: ../web/statuspage.c:386 msgid "Start All" -msgstr "Start nmbd" +msgstr "Start Alle" #: ../web/statuspage.c:393 msgid "Active Connections" -- cgit From 2dcb369a6604d90d7f9465ce362feccac798111e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Jan 2004 19:55:03 +0000 Subject: Fix from Luke Howard for incorrect early free(). Jeremy. (This used to be commit e763a220f492bb8a9cacf31c07809c4866379bb6) --- source3/smbd/sesssetup.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 2c38cd3eb3..80be9da53b 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -241,11 +241,10 @@ static int reply_spnego_kerberos(connection_struct *conn, pw = smb_getpwnam( user ); - SAFE_FREE(user); - SAFE_FREE(client); - if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); + SAFE_FREE(user); + SAFE_FREE(client); data_blob_free(&ap_rep); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -257,14 +256,17 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) { DEBUG(1,("make_server_info_from_pw failed!\n")); + SAFE_FREE(user); + SAFE_FREE(client); data_blob_free(&ap_rep); return ERROR_NT(ret); } /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, session_key, nullblob, user); + sess_vuid = register_vuid(server_info, session_key, nullblob, client); - free(user); + SAFE_FREE(user); + SAFE_FREE(client); if (sess_vuid == -1) { ret = NT_STATUS_LOGON_FAILURE; -- cgit From d5f77ecd29f0030462fcac1ce786a50f761e2ec1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 7 Jan 2004 19:58:14 +0000 Subject: commiting jra's fix for Exchange clear test auth (This used to be commit 05dd3383010ba6f44370fc302ee00b7680937176) --- source3/rpc_parse/parse_net.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index 89673dd0e3..90cd348f5a 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -1317,9 +1317,10 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, memset((char *)usr->padding, '\0', sizeof(usr->padding)); +#if 0 /* JRATEST - exchange auth test. */ if (lm_session_key != NULL) memcpy(usr->padding, lm_session_key, sizeof(usr->user_sess_key)); - +#endif num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids); -- cgit From d4f81697d7e95b1fe0b7f8be10e1a87142ce6cfa Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 7 Jan 2004 21:41:48 +0000 Subject: Prototype version of trust passwords moved to SAM/pdb. This is backend-independent part ie. interface - does build and (it seems) doesn't break anything else. rafal (This used to be commit 9ce6dc6476202d9db6ea1c2deab93e454e4db546) --- source3/include/passdb.h | 55 +++++++++++++++- source3/passdb/pdb_interface.c | 141 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 1 deletion(-) diff --git a/source3/include/passdb.h b/source3/include/passdb.h index d7f11781fe..c12cf10cf2 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -78,6 +78,15 @@ enum pdb_group_elements { PDB_GROUP_COUNT }; +enum pdb_trust_passwd_elements { + PDB_TRUST_PASS, + PDB_TRUST_SID, + PDB_TRUST_NAME, + PDB_TRUST_MODTIME, + PDB_TRUST_FLAGS, + + PDB_TRUST_COUNT +}; enum pdb_value_state { PDB_DEFAULT=0, @@ -186,6 +195,26 @@ typedef struct _GROUP_INFO { } GROUP_INFO; +typedef struct sam_trust_passwd { + TALLOC_CTX *mem_ctx; + + void (*free_fn)(struct sam_trust_passwd **); + + struct pdb_methods *methods; + + struct trust_passwd_data { + uint16 flags; /* flags */ + size_t uni_name_len; /* unicode name length */ + smb_ucs2_t uni_name[32]; /* unicode domain name */ + fstring pass; /* trust password */ + time_t mod_time; /* last change time */ + DOM_SID domain_sid; /* trusted domain sid */ + } private; + +} SAM_TRUST_PASSWD; + + + /***************************************************************** Functions to be implemented by the new (v2) passdb API ****************************************************************/ @@ -195,7 +224,7 @@ typedef struct _GROUP_INFO { * this SAMBA will load. Increment this if *ANY* changes are made to the interface. */ -#define PASSDB_INTERFACE_VERSION 4 +#define PASSDB_INTERFACE_VERSION 5 typedef struct pdb_context { @@ -267,6 +296,18 @@ typedef struct pdb_context NTSTATUS (*pdb_get_group_uids)(struct pdb_context *context, const DOM_SID *group, uid_t **members, int *num_members); + /* trust password functions */ + + NTSTATUS (*pdb_gettrustpwent)(struct pdb_context *context, SAM_TRUST_PASSWD *trust); + + NTSTATUS (*pdb_gettrustpwsid)(struct pdb_context *context, SAM_TRUST_PASSWD *trust, const DOM_SID *sid); + + NTSTATUS (*pdb_add_trust_passwd)(struct pdb_context *context, SAM_TRUST_PASSWD* trust); + + NTSTATUS (*pdb_update_trust_passwd)(struct pdb_context *context, SAM_TRUST_PASSWD* trust); + + NTSTATUS (*pdb_delete_trust_passwd)(struct pdb_context *context, SAM_TRUST_PASSWD* trust); + void (*free_fn)(struct pdb_context **); TALLOC_CTX *mem_ctx; @@ -347,6 +388,18 @@ typedef struct pdb_methods void *private_data; /* Private data of some kind */ void (*free_private_data)(void **); + + /* trust password functions */ + + NTSTATUS (*gettrustpwent)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust); + + NTSTATUS (*gettrustpwsid)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const DOM_SID *sid); + + NTSTATUS (*add_trust_passwd)(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust); + + NTSTATUS (*update_trust_passwd)(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust); + + NTSTATUS (*delete_trust_passwd)(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust); } PDB_METHODS; diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index d548081e78..26cbb21ee9 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -385,6 +385,109 @@ static NTSTATUS context_enum_group_mapping(struct pdb_context *context, num_entries, unix_only); } +static NTSTATUS context_gettrustpwent(struct pdb_context *context, + SAM_TRUST_PASSWD *trust) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + struct pdb_methods *cur_methods; + + if (!context) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + cur_methods = context->pdb_methods; + + while (cur_methods) { + ret = cur_methods->gettrustpwent(cur_methods, trust); + if (NT_STATUS_IS_OK(ret)) { + trust->methods = cur_methods; + return ret; + } + cur_methods = cur_methods->next; + } + + return ret; +} + +static NTSTATUS context_gettrustpwsid(struct pdb_context *context, + SAM_TRUST_PASSWD *trust, + const DOM_SID *sid) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + struct pdb_methods *cur_methods; + + if (!context) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + cur_methods = context->pdb_methods; + + while (cur_methods) { + ret = cur_methods->gettrustpwsid(cur_methods, trust, sid); + if (NT_STATUS_IS_OK(ret)) { + trust->methods = cur_methods; + return ret; + } + cur_methods = cur_methods->next; + } + + return ret; +} + +static NTSTATUS context_add_trust_passwd(struct pdb_context *context, + SAM_TRUST_PASSWD *trust) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + struct pdb_methods *methods; + + if (!context) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods->add_trust_passwd(context->pdb_methods, trust); +} + +static NTSTATUS context_update_trust_passwd(struct pdb_context *context, + SAM_TRUST_PASSWD *trust) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + struct pdb_methods *methods; + + if (!context) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + if (!trust || !trust->methods) { + DEBUG(0, ("invalid trust pointer specified!\n")); + return ret; + } + + return trust->methods->update_trust_passwd(trust->methods, trust); +} + +static NTSTATUS context_delete_trust_passwd(struct pdb_context *context, + SAM_TRUST_PASSWD *trust) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + struct pdb_methods *methods; + + if (!context) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + if (!trust || !trust->methods) { + DEBUG(0, ("invalid trust pointer specified!\n")); + return ret; + } + + return trust->methods->delete_trust_passwd(trust->methods, trust); +} + /****************************************************************** Free and cleanup a pdb context, any associated data and anything that the attached modules might have associated. @@ -500,6 +603,11 @@ static NTSTATUS make_pdb_context(struct pdb_context **context) (*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry; (*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry; (*context)->pdb_enum_group_mapping = context_enum_group_mapping; + (*context)->pdb_gettrustpwent = context_gettrustpwent; + (*context)->pdb_gettrustpwsid = context_gettrustpwsid; + (*context)->pdb_add_trust_passwd = context_add_trust_passwd; + (*context)->pdb_update_trust_passwd = context_update_trust_passwd; + (*context)->pdb_delete_trust_passwd = context_delete_trust_passwd; (*context)->free_fn = free_pdb_context; @@ -840,6 +948,33 @@ static void pdb_default_endsampwent(struct pdb_methods *methods) return; /* NT_STATUS_NOT_IMPLEMENTED; */ } +static NTSTATUS pdb_default_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_default_gettrustpwsid(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust, + const DOM_SID* sid) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_default_add_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_default_update_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_default_delete_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) { *methods = talloc(mem_ctx, sizeof(struct pdb_methods)); @@ -866,6 +1001,12 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry; (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry; (*methods)->enum_group_mapping = pdb_default_enum_group_mapping; + + (*methods)->gettrustpwent = pdb_default_gettrustpwent; + (*methods)->gettrustpwsid = pdb_default_gettrustpwsid; + (*methods)->add_trust_passwd = pdb_default_add_trust_passwd; + (*methods)->update_trust_passwd = pdb_default_update_trust_passwd; + (*methods)->delete_trust_passwd = pdb_default_delete_trust_passwd; return NT_STATUS_OK; } -- cgit From 6f71333c082e362caeec6c4cca483b9e2014cc22 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 7 Jan 2004 21:47:36 +0000 Subject: Fixes to doxygen comment. (This used to be commit 4f92db99be8feaccebe654103dd6c227c66e5bdc) --- source3/auth/auth_domain.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 0f34bcc0e2..31ffd88083 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -27,13 +27,16 @@ extern BOOL global_machine_password_needs_changing; /** - * Connect to a remote server for domain security authenticaion. + * Connect to a remote server for (inter)domain security authenticaion. * * @param cli the cli to return containing the active connection * @param server either a machine name or text IP address to * connect to. + * @param setup_creds_as domain account to setup credentials as + * @param sec_chan switch value to distinguish between domain + * member and interdomain authentication * @param trust_passwd the trust password to establish the - * credentials with. + * credentials * **/ -- cgit From e439a065856a9e43f2a80e10ab1c98bb8117aaa0 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 7 Jan 2004 21:50:30 +0000 Subject: Typo fix. rafal (This used to be commit 4a2bd4de3f5a99bc19013a2878659e8686606e30) --- source3/passdb/passdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 7f1861f0bf..8fbd8d4cdc 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -164,7 +164,7 @@ NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user) /************************************************************* - Alloc memory and initialises a struct sam_passwd. + Allocates memory and initialises a struct sam_passwd. ************************************************************/ NTSTATUS pdb_init_sam(SAM_ACCOUNT **user) -- cgit From f71a02865bfd14f9d0d25912859d5f657027f8f4 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 7 Jan 2004 21:53:19 +0000 Subject: This was cut-n-paste mistake, I guess... :) rafal (This used to be commit f912d8c3403071582f776886f9793e3289b285b6) --- source3/passdb/pdb_gums.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/pdb_gums.c b/source3/passdb/pdb_gums.c index 5e1e5e392f..25dc565253 100644 --- a/source3/passdb/pdb_gums.c +++ b/source3/passdb/pdb_gums.c @@ -1,5 +1,5 @@ /* - * 'Guest' password backend for samba + * GUMS password backend for samba * Copyright (C) Jelmer Vernooij 2002 * Copyright (C) Andrew Bartlett 2003 * -- cgit From be7b27b78f7f2ea6e2b6251e33f09bd44f23b78f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Jan 2004 23:21:25 +0000 Subject: Fix for bug #922. Fast path not called for strlower_m() and strupper_m(). From ab@samba.org (Alexander Bokovoy). Jeremy. (This used to be commit 88c51454327533f8bc06ce1cd479370aabefdf81) --- source3/lib/util_str.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index fd339370b3..f552b38e67 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1298,7 +1298,7 @@ void strlower_m(char *s) supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars) */ - while (*s && !(((unsigned char)s[0]) & 0x7F)) { + while (*s && !(((unsigned char)s[0]) & 0x80)) { *s = tolower((unsigned char)*s); s++; } @@ -1322,7 +1322,7 @@ void strupper_m(char *s) supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars) */ - while (*s && !(((unsigned char)s[0]) & 0x7F)) { + while (*s && !(((unsigned char)s[0]) & 0x80)) { *s = toupper((unsigned char)*s); s++; } -- cgit From 5982f2c17b38ba865371d648976cdb1282cf61e7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 8 Jan 2004 22:21:39 +0000 Subject: fix segfault when sid_ptr == 0 in DsEnumDomainTrusts() reply (This used to be commit 36d985a75faa5ebda1c8c7de1e3ab5d7a51a9c10) --- source3/nsswitch/winbindd_util.c | 5 ++--- source3/rpc_client/cli_ds.c | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index f29ed37650..4cc43e85d6 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -107,8 +107,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const /* Create new domain entry */ - if ((domain = (struct winbindd_domain *) - malloc(sizeof(*domain))) == NULL) + if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain))) == NULL) return NULL; /* Fill in fields */ @@ -146,7 +145,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const DEBUG(1,("Added domain %s %s %s\n", domain->name, domain->alt_name, - sid?sid_string_static(&domain->sid):"")); + &domain->sid?sid_string_static(&domain->sid):"")); return domain; } diff --git a/source3/rpc_client/cli_ds.c b/source3/rpc_client/cli_ds.c index f8455edcd9..8c2821d5af 100644 --- a/source3/rpc_client/cli_ds.c +++ b/source3/rpc_client/cli_ds.c @@ -127,19 +127,19 @@ NTSTATUS cli_ds_enum_domain_trusts(struct cli_state *cli, TALLOC_CTX *mem_ctx, (*trusts)[i].trust_attributes = r.domains.trusts[i].trust_attributes; (*trusts)[i].guid = r.domains.trusts[i].guid; - if (&r.domains.trusts[i].sid_ptr) { + if (r.domains.trusts[i].sid_ptr) { sid_copy(&(*trusts)[i].sid, &r.domains.trusts[i].sid.sid); } else { ZERO_STRUCT((*trusts)[i].sid); } - if (&r.domains.trusts[i].netbios_ptr) { + if (r.domains.trusts[i].netbios_ptr) { (*trusts)[i].netbios_domain = unistr2_tdup( mem_ctx, &r.domains.trusts[i].netbios_domain ); } else { (*trusts)[i].netbios_domain = NULL; } - if (&r.domains.trusts[i].dns_ptr) { + if (r.domains.trusts[i].dns_ptr) { (*trusts)[i].dns_domain = unistr2_tdup( mem_ctx, &r.domains.trusts[i].dns_domain ); } else { (*trusts)[i].dns_domain = NULL; -- cgit From 19e9a7e1b947d7f26b9923a9c89ab088d76e340d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 9 Jan 2004 15:36:07 +0000 Subject: fix some warnings from the Sun compiler; also merge some of abartlet's error code changes form 3.0 (This used to be commit 2279e98cb81faaf8a4e971fec339955f14c23858) --- source3/include/ads.h | 18 +++++++++--------- source3/include/asn_1.h | 10 +++++----- source3/libads/ads_status.c | 37 +++++++++++++++++++++++-------------- source3/libsmb/ntlmssp.c | 2 +- source3/nsswitch/winbindd_ads.c | 2 +- source3/rpc_parse/parse_prs.c | 8 ++++---- source3/rpc_server/srv_samr_nt.c | 2 +- source3/utils/net_ads.c | 2 +- 8 files changed, 45 insertions(+), 36 deletions(-) diff --git a/source3/include/ads.h b/source3/include/ads.h index b85ad21fba..65a5ade556 100644 --- a/source3/include/ads.h +++ b/source3/include/ads.h @@ -39,8 +39,8 @@ typedef struct { } ADS_STRUCT; /* there are 5 possible types of errors the ads subsystem can produce */ -enum ads_error_type {ADS_ERROR_KRB5, ADS_ERROR_GSS, - ADS_ERROR_LDAP, ADS_ERROR_SYSTEM, ADS_ERROR_NT}; +enum ads_error_type {ENUM_ADS_ERROR_KRB5, ENUM_ADS_ERROR_GSS, + ENUM_ADS_ERROR_LDAP, ENUM_ADS_ERROR_SYSTEM, ENUM_ADS_ERROR_NT}; typedef struct { enum ads_error_type error_type; @@ -48,7 +48,7 @@ typedef struct { int rc; NTSTATUS nt_status; } err; - /* For error_type = ADS_ERROR_GSS minor_status describe GSS API error */ + /* For error_type = ENUM_ADS_ERROR_GSS minor_status describe GSS API error */ /* Where rc represents major_status of GSS API error */ int minor_status; } ADS_STATUS; @@ -61,13 +61,13 @@ typedef void **ADS_MODLIST; /* macros to simplify error returning */ #define ADS_ERROR(rc) ADS_ERROR_LDAP(rc) -#define ADS_ERROR_LDAP(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0) -#define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc?rc:EINVAL, 0) -#define ADS_ERROR_KRB5(rc) ads_build_error(ADS_ERROR_KRB5, rc, 0) -#define ADS_ERROR_GSS(rc, minor) ads_build_error(ADS_ERROR_GSS, rc, minor) -#define ADS_ERROR_NT(rc) ads_build_nt_error(ADS_ERROR_NT,rc) +#define ADS_ERROR_LDAP(rc) ads_build_error(ENUM_ADS_ERROR_LDAP, rc, 0) +#define ADS_ERROR_SYSTEM(rc) ads_build_error(ENUM_ADS_ERROR_SYSTEM, rc?rc:EINVAL, 0) +#define ADS_ERROR_KRB5(rc) ads_build_error(ENUM_ADS_ERROR_KRB5, rc, 0) +#define ADS_ERROR_GSS(rc, minor) ads_build_error(ENUM_ADS_ERROR_GSS, rc, minor) +#define ADS_ERROR_NT(rc) ads_build_nt_error(ENUM_ADS_ERROR_NT,rc) -#define ADS_ERR_OK(status) ((status.error_type == ADS_ERROR_NT) ? NT_STATUS_IS_OK(status.err.nt_status):(status.err.rc == 0)) +#define ADS_ERR_OK(status) ((status.error_type == ENUM_ADS_ERROR_NT) ? NT_STATUS_IS_OK(status.err.nt_status):(status.err.rc == 0)) #define ADS_SUCCESS ADS_ERROR(0) /* time between reconnect attempts */ diff --git a/source3/include/asn_1.h b/source3/include/asn_1.h index 7d4da0db0c..796c8bb740 100644 --- a/source3/include/asn_1.h +++ b/source3/include/asn_1.h @@ -60,10 +60,10 @@ typedef struct { #define SPNEGO_NEG_RESULT_REJECT 2 /* not really ASN.1, but RFC 1964 */ -#define TOK_ID_KRB_AP_REQ "\x01\x00" -#define TOK_ID_KRB_AP_REP "\x02\x00" -#define TOK_ID_KRB_ERROR "\x03\x00" -#define TOK_ID_GSS_GETMIC "\x01\x01" -#define TOK_ID_GSS_WRAP "\x02\x01" +#define TOK_ID_KRB_AP_REQ (uchar*)"\x01\x00" +#define TOK_ID_KRB_AP_REP (uchar*)"\x02\x00" +#define TOK_ID_KRB_ERROR (uchar*)"\x03\x00" +#define TOK_ID_GSS_GETMIC (uchar*)"\x01\x01" +#define TOK_ID_GSS_WRAP (uchar*)"\x02\x01" #endif /* _ASN_1_H */ diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index 11f9d66b92..463f647f9c 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -31,10 +31,10 @@ ADS_STATUS ads_build_error(enum ads_error_type etype, { ADS_STATUS ret; - if (etype == ADS_ERROR_NT) { - DEBUG(0,("don't use ads_build_error with ADS_ERROR_NT!\n")); + if (etype == ENUM_ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_error with ENUM_ADS_ERROR_NT!\n")); ret.err.rc = -1; - ret.error_type = ADS_ERROR_SYSTEM; + ret.error_type = ENUM_ADS_ERROR_SYSTEM; ret.minor_status = 0; return ret; } @@ -50,10 +50,10 @@ ADS_STATUS ads_build_nt_error(enum ads_error_type etype, { ADS_STATUS ret; - if (etype != ADS_ERROR_NT) { - DEBUG(0,("don't use ads_build_nt_error without ADS_ERROR_NT!\n")); + if (etype != ENUM_ADS_ERROR_NT) { + DEBUG(0,("don't use ads_build_nt_error without ENUM_ADS_ERROR_NT!\n")); ret.err.rc = -1; - ret.error_type = ADS_ERROR_SYSTEM; + ret.error_type = ENUM_ADS_ERROR_SYSTEM; ret.minor_status = 0; return ret; } @@ -69,14 +69,23 @@ ADS_STATUS ads_build_nt_error(enum ads_error_type etype, */ NTSTATUS ads_ntstatus(ADS_STATUS status) { - if (status.error_type == ADS_ERROR_NT){ + if (status.error_type == ENUM_ADS_ERROR_NT){ return status.err.nt_status; } #ifdef HAVE_LDAP - if ((status.error_type == ADS_ERROR_LDAP) + if ((status.error_type == ENUM_ADS_ERROR_LDAP) && (status.err.rc == LDAP_NO_MEMORY)) { return NT_STATUS_NO_MEMORY; } +#endif +#ifdef HAVE_KRB5 + if (status.error_type == ENUM_ADS_ERROR_KRB5) { + if (status.err.rc == KRB5KDC_ERR_PREAUTH_FAILED) { + return NT_STATUS_LOGON_FAILURE; + } else if (status.err.rc == KRB5_KDC_UNREACH) { + return NT_STATUS_NO_LOGON_SERVERS; + } + } #endif if (ADS_ERR_OK(status)) return NT_STATUS_OK; return NT_STATUS_UNSUCCESSFUL; @@ -94,18 +103,18 @@ const char *ads_errstr(ADS_STATUS status) msg_ctx = 0; switch (status.error_type) { - case ADS_ERROR_SYSTEM: + case ENUM_ADS_ERROR_SYSTEM: return strerror(status.err.rc); #ifdef HAVE_LDAP - case ADS_ERROR_LDAP: + case ENUM_ADS_ERROR_LDAP: return ldap_err2string(status.err.rc); #endif #ifdef HAVE_KRB5 - case ADS_ERROR_KRB5: + case ENUM_ADS_ERROR_KRB5: return error_message(status.err.rc); #endif #ifdef HAVE_GSSAPI - case ADS_ERROR_GSS: + case ENUM_ADS_ERROR_GSS: { uint32 minor; @@ -122,8 +131,8 @@ const char *ads_errstr(ADS_STATUS status) return ret; } #endif - case ADS_ERROR_NT: - return nt_errstr(ads_ntstatus(status)); + case ENUM_ADS_ERROR_NT: + return get_friendly_nt_error_msg(ads_ntstatus(status)); default: return "Unknown ADS error type!? (not compiled in?)"; } diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 40d7f41109..a80b4b66b0 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -974,7 +974,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); DEBUG(5, ("challenge is: \n")); - dump_data(5, session_nonce_hash, 8); + dump_data(5, (const char *)session_nonce_hash, 8); nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBNTencrypt(ntlmssp_state->password, diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 90b83bccd0..ec93d494d0 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -67,7 +67,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) /* if we get ECONNREFUSED then it might be a NT4 server, fall back to MSRPC */ - if (status.error_type == ADS_ERROR_SYSTEM && + if (status.error_type == ENUM_ADS_ERROR_SYSTEM && status.err.rc == ECONNREFUSED) { DEBUG(1,("Trying MSRPC methods\n")); if (domain->methods == &cache_methods) { diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 9056348239..58652fa0c5 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -1574,9 +1574,9 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags, checksum after the decode, below */ DEBUG(2, ("netsec_decode: FAILED: packet sequence number:\n")); - dump_data(2, verf->seq_num, sizeof(verf->seq_num)); + dump_data(2, (const char*)verf->seq_num, sizeof(verf->seq_num)); DEBUG(2, ("should be:\n")); - dump_data(2, seq_num, sizeof(seq_num)); + dump_data(2, (const char*)seq_num, sizeof(seq_num)); return False; } @@ -1584,9 +1584,9 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags, if (memcmp(verf->sig, netsec_sig, sizeof(verf->sig))) { /* Validate that the other end sent the expected header */ DEBUG(2, ("netsec_decode: FAILED: packet header:\n")); - dump_data(2, verf->sig, sizeof(verf->sig)); + dump_data(2, (const char*)verf->sig, sizeof(verf->sig)); DEBUG(2, ("should be:\n")); - dump_data(2, netsec_sig, sizeof(netsec_sig)); + dump_data(2, (const char*)netsec_sig, sizeof(netsec_sig)); return False; } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index bd26ce6849..b9974cba8a 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -4277,7 +4277,7 @@ NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, if ( is_user ) { GROUP_MAP *mappings = NULL; - uint32 num_groups, i; + int num_groups, i; struct group *grp2; if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) { diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 9ee2f3c093..24ae9a8811 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -688,7 +688,7 @@ int net_ads_join(int argc, const char **argv) rc = ads_search_dn(ads, &res, dn, NULL); ads_msgfree(ads, res); - if (rc.error_type == ADS_ERROR_LDAP && rc.err.rc == LDAP_NO_SUCH_OBJECT) { + if (rc.error_type == ENUM_ADS_ERROR_LDAP && rc.err.rc == LDAP_NO_SUCH_OBJECT) { d_printf("ads_join_realm: organizational unit %s does not exist (dn:%s)\n", org_unit, dn); return -1; -- cgit From f2008e22946ebf676867fb2a3f4c8665b027e664 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 11 Jan 2004 13:21:03 +0000 Subject: update copyright to -2004 metze (This used to be commit fcb3c9c61ecd787b8d3e5a53ee8f9e04daae76fe) --- source3/nmbd/nmbd.c | 2 +- source3/nsswitch/winbindd.c | 2 +- source3/smbd/server.c | 2 +- source3/wrepld/server.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 36aa2e2485..880de7f91b 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -662,7 +662,7 @@ static BOOL open_sockets(BOOL isdaemon, int port) reopen_logs(); DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) ); - DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2003\n" ) ); + DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2004\n" ) ); if ( !reload_nmbd_services(False) ) return(-1); diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 8ce528d2b0..4c03522461 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -841,7 +841,7 @@ int main(int argc, char **argv) reopen_logs(); DEBUG(1, ("winbindd version %s started.\n", SAMBA_VERSION_STRING) ); - DEBUGADD( 1, ( "Copyright The Samba Team 2000-2003\n" ) ); + DEBUGADD( 1, ( "Copyright The Samba Team 2000-2004\n" ) ); if (!reload_services_file(False)) { DEBUG(0, ("error opening config file\n")); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 89d6f92e98..e7aa41e343 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -745,7 +745,7 @@ void build_options(BOOL screen); reopen_logs(); DEBUG(0,( "smbd version %s started.\n", SAMBA_VERSION_STRING)); - DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2003\n")); + DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2004\n")); DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n", (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid())); diff --git a/source3/wrepld/server.c b/source3/wrepld/server.c index 25de680982..80694a616b 100644 --- a/source3/wrepld/server.c +++ b/source3/wrepld/server.c @@ -587,7 +587,7 @@ static void process(void) reopen_logs(); DEBUG(1,( "wrepld version %s started.\n", SAMBA_VERSION_STRING)); - DEBUGADD(1,( "Copyright Andrew Tridgell and the Samba Team 1992-2002\n")); + DEBUGADD(1,( "Copyright Andrew Tridgell and the Samba Team 1992-2004\n")); DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n", (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid())); -- cgit From 60079bd15bee7fe71dd43cb131f6198ca28f74eb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Jan 2004 13:40:48 +0000 Subject: Fix --with-fhs for swatdir (This used to be commit 69a9cfdad809a9b3fc7f6dc4ad5a708b6559b714) --- source3/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/Makefile.in b/source3/Makefile.in index d89c2c3481..923f4dbd5b 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -85,6 +85,7 @@ PRIVATEDIR = @privatedir@ SMB_PASSWD_FILE = $(PRIVATEDIR)/smbpasswd PRIVATE_DIR = $(PRIVATEDIR) +DATADIR = @datadir@ # This is where SWAT images and help files go SWATDIR = @swatdir@ -- cgit From 0c9adb69858c7572320d18c0fd187dd6e885f17d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 13 Jan 2004 17:55:43 +0000 Subject: sync HEAD with recent changes in 3.0 (This used to be commit c98399e3c9d74e19b7c9d806ca8028b48866931e) --- source3/Makefile.in | 26 +- source3/auth/auth_domain.c | 4 +- source3/bin/.cvsignore | 6 +- source3/client/mount.cifs.c | 680 ++++++++++++++++++++++----------- source3/configure.in | 101 +++-- source3/include/printing.h | 2 - source3/include/samba_linux_quota.h | 336 ++++++++++++++++ source3/include/samba_xfs_quota.h | 165 ++++++++ source3/include/sysquotas.h | 152 +------- source3/intl/lang_tdb.c | 3 +- source3/lib/charcnv.c | 4 +- source3/lib/sysquotas.c | 529 ------------------------- source3/lib/sysquotas_4A.c | 318 +++++++++++++++ source3/lib/sysquotas_linux.c | 485 +++++++++++++++++++++++ source3/lib/sysquotas_xfs.c | 306 +++++++++++++++ source3/lib/talloctort.c | 4 +- source3/lib/time.c | 5 +- source3/lib/util_str.c | 6 +- source3/libads/sasl.c | 17 +- source3/libsmb/cliconnect.c | 46 ++- source3/libsmb/clikrb5.c | 24 +- source3/libsmb/clispnego.c | 17 +- source3/libsmb/namequery.c | 86 +++-- source3/locking/locking.c | 4 +- source3/nmbd/nmbd_processlogon.c | 2 +- source3/nsswitch/wbinfo.c | 26 +- source3/nsswitch/winbind_nss_freebsd.c | 81 ++++ source3/nsswitch/winbindd.c | 2 + source3/nsswitch/winbindd.h | 3 +- source3/nsswitch/winbindd_ads.c | 2 +- source3/nsswitch/winbindd_cache.c | 6 +- source3/nsswitch/winbindd_cm.c | 103 ++++- source3/nsswitch/winbindd_group.c | 62 ++- source3/nsswitch/winbindd_misc.c | 16 +- source3/nsswitch/winbindd_nss.h | 3 +- source3/nsswitch/winbindd_rpc.c | 13 +- source3/nsswitch/winbindd_sid.c | 8 +- source3/nsswitch/winbindd_user.c | 52 ++- source3/nsswitch/winbindd_util.c | 45 ++- source3/nsswitch/wins.c | 4 +- source3/param/loadparm.c | 18 +- source3/passdb/secrets.c | 38 ++ source3/printing/notify.c | 1 + source3/printing/print_cups.c | 1 + source3/printing/print_generic.c | 1 + source3/printing/printing.c | 1 + source3/printing/printing_db.c | 1 + source3/rpc_client/cli_lsarpc.c | 89 +++-- source3/rpc_server/srv_samr_nt.c | 17 +- source3/rpcclient/cmd_lsarpc.c | 30 +- source3/rpcclient/cmd_spoolss.c | 2 +- source3/script/installswat.sh | 2 +- source3/script/mkbuildoptions.awk | 16 +- source3/smbd/chgpasswd.c | 81 ++-- source3/smbd/quotas.c | 159 +++++--- source3/tdb/tdb.c | 2 + source3/tests/crack.c | 5 + source3/utils/net_rpc.c | 40 +- source3/utils/ntlm_auth.c | 15 +- source3/utils/smbcontrol.c | 2 +- source3/utils/smbget.c | 574 ++++++++++++++++++++++++++++ 61 files changed, 3485 insertions(+), 1364 deletions(-) create mode 100644 source3/include/samba_linux_quota.h create mode 100644 source3/include/samba_xfs_quota.h create mode 100644 source3/lib/sysquotas_4A.c create mode 100644 source3/lib/sysquotas_linux.c create mode 100644 source3/lib/sysquotas_xfs.c create mode 100644 source3/nsswitch/winbind_nss_freebsd.c create mode 100644 source3/tests/crack.c create mode 100644 source3/utils/smbget.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 923f4dbd5b..68aead0fc2 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -85,7 +85,6 @@ PRIVATEDIR = @privatedir@ SMB_PASSWD_FILE = $(PRIVATEDIR)/smbpasswd PRIVATE_DIR = $(PRIVATEDIR) -DATADIR = @datadir@ # This is where SWAT images and help files go SWATDIR = @swatdir@ @@ -202,11 +201,11 @@ UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \ PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o param/modconf.o -KRBCLIENT_OBJ = libads/kerberos.o +KRBCLIENT_OBJ = libads/kerberos.o libads/ads_status.o LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \ libads/krb5_setpw.o libads/ldap_user.o \ - libads/ads_struct.o libads/ads_status.o \ + libads/ads_struct.o \ libads/disp_sec.o libads/ads_utils.o libads/ldap_utils.o \ libads/ads_ldap.o libads/authdata.o @@ -362,8 +361,9 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \ smbd/posix_acls.o lib/sysacls.o lib/server_mutex.o \ smbd/process.o smbd/service.o smbd/error.o \ - printing/printfsp.o \ - lib/sysquotas.o smbd/change_trust_pw.o smbd/fake_file.o \ + printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \ + lib/sysquotas_xfs.o lib/sysquotas_4A.o \ + smbd/change_trust_pw.o smbd/fake_file.o \ smbd/quotas.o smbd/ntquotas.o lib/afs.o \ $(MANGLE_OBJ) @VFS_STATIC@ @@ -450,6 +450,8 @@ PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o +SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ) $(SECRETS_OBJ) + RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \ rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o \ @@ -730,6 +732,12 @@ MAKEDIR = || exec false; \ -o $@ @BROKEN_CC@ -mv `echo $@ | sed 's%^.*/%%g'` $@ +# this adds support for precompiled headers. To use it, install a snapshot +# of gcc-3.4 and run 'make pch' before you do the main build. +pch: + rm -f $(srcdir)/include/includes.h.gch + $(CC) -I. -I$(srcdir) $(FLAGS) -c $(srcdir)/include/includes.h -o $(srcdir)/include/includes.h.gch + # These dependencies are only approximately correct: we want to make # sure Samba's paths are updated if ./configure is re-run. Really it # would be nice if "make prefix=/opt/samba all" also rebuilt things, @@ -746,7 +754,7 @@ dynconfig.@PICSUFFIX@: dynconfig.c Makefile @echo Compiling $*.c with @PICFLAGS@ @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c $< -o $*.@PICSUFFIX@ @BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@ -@POBAD_CC@ @mv $*.@PICSUFFIX@.o $@ +@POBAD_CC@ -@mv $*.@PICSUFFIX@.o $@ lib/version.o: lib/version.c include/version.h @echo Compiling $*.c @@ -870,6 +878,10 @@ bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(LDAP_LIBS) +bin/smbget@EXEEXT@: $(SMBGET_OBJ) @BUILD_POPT@ bin/.dummy + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(SMBGET_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(KRB5LIBS) $(LDAP_LIBS) @@ -1034,7 +1046,7 @@ bin/librpc_epmapper.@SHLIBEXT@: $(RPC_EPMAPPER_OBJ) bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy @echo "Linking $@" - @$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + @$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) # Please don't add .o files to libnss_winbind, libnss_wins, or the pam_winbind # libraries. Add to the appropriate PICOBJ variable instead. diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 31ffd88083..0bf2031a37 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -33,10 +33,10 @@ extern BOOL global_machine_password_needs_changing; * @param server either a machine name or text IP address to * connect to. * @param setup_creds_as domain account to setup credentials as - * @param sec_chan switch value to distinguish between domain + * @param sec_chan a switch value to distinguish between domain * member and interdomain authentication * @param trust_passwd the trust password to establish the - * credentials + * credentials with. * **/ diff --git a/source3/bin/.cvsignore b/source3/bin/.cvsignore index 013a5ba6c1..aad6091960 100644 --- a/source3/bin/.cvsignore +++ b/source3/bin/.cvsignore @@ -5,6 +5,7 @@ debug2html editreg locktest locktest2 +log2pcap make_printerdef make_smbcodepage make_unicodemap @@ -28,6 +29,7 @@ smbcquotas smbd smbfilter smbgroupedit +smbiconv smbmnt smbmount smbpasswd @@ -37,7 +39,6 @@ smbstatus smbtorture smbtree smbumount -smbiconv swat t_push_ucs2 t_snprintf @@ -45,11 +46,10 @@ t_strcmp t_stringoverflow talloctort tdbbackup +tdbdump testparm testprns vfstest -log2pcap wbinfo winbindd wrepld -tdbdump diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index 43b20e9d50..8c23cc2212 100755 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -1,6 +1,27 @@ +/* + Mount helper utility for Linux CIFS VFS (virtual filesystem) client + Copyright (C) 2003 Steve French (sfrench@us.ibm.com) + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include +#include #include #include #include @@ -14,10 +35,14 @@ #include #include #include +#include -#define MOUNT_CIFS_VERSION "1" +#define MOUNT_CIFS_VERSION_MAJOR "1" +#define MOUNT_CIFS_VERSION_MINOR "0" -extern char *getusername(void); +#ifndef MOUNT_CIFS_VENDOR_SUFFIX +#define MOUNT_CIFS_VENDOR_SUFFIX "" +#endif char * thisprogram; int verboseflag = 0; @@ -41,17 +66,20 @@ char * mountpassword = NULL; BB end finish BB */ -void mount_cifs_usage() +static void mount_cifs_usage(void) { - printf("\nUsage: %s remotetarget dir\n", thisprogram); - printf("\nMount the remotetarget, specified as either a UNC name or "); - printf(" CIFS URL, to the local directory, dir.\n"); - + printf("\nUsage: %s -o \n", thisprogram); + printf("\nMount the remote target, specified as a UNC name,"); + printf(" to a local directory.\n"); + if(mountpassword) { + memset(mountpassword,0,64); + free(mountpassword); + } exit(1); } /* caller frees username if necessary */ -char * getusername() { +static char * getusername(void) { char *username = NULL; struct passwd *password = getpwuid(getuid()); @@ -61,25 +89,185 @@ char * getusername() { return username; } -char * parse_cifs_url(unc_name) +char * parse_cifs_url(char * unc_name) { printf("\ncifs url %s\n",unc_name); + return NULL; +} + +static int open_cred_file(char * file_name) +{ + char * line_buf; + char * temp_val; + FILE * fs; + int i, length; + fs = fopen(file_name,"r"); + if(fs == NULL) + return errno; + line_buf = malloc(4096); + if(line_buf == NULL) + return -ENOMEM; + + while(fgets(line_buf,4096,fs)) { + /* parse line from credential file */ + + /* eat leading white space */ + for(i=0;i<4096;i++) { + if(line_buf[i] == '\0') + break; + else if((line_buf[i] != ' ') && (line_buf[i] != '\t')) + break; + line_buf++; + } + + if (strncasecmp("username",line_buf,8) == 0) { + temp_val = strchr(line_buf + i,'='); + if(temp_val) { + /* go past equals sign */ + temp_val++; + length = strlen(temp_val); + if(length > 4086) { + printf("cifs.mount failed due to malformed username in credentials file"); + memset(line_buf,0,4096); + if(mountpassword) { + memset(mountpassword,0,64); + } + exit(1); + } else { + got_user = 1; + user_name = calloc(1 + length,1); + /* BB adding free of user_name string before exit, + not really necessary but would be cleaner */ + strncpy(user_name,temp_val, length); + } + } + } else if (strncasecmp("password",line_buf,8) == 0) { + temp_val = strchr(line_buf+i,'='); + if(temp_val) { + /* go past equals sign */ + temp_val++; + length = strlen(temp_val); + if(length > 64) { + printf("cifs.mount failed: password in credentials file too long\n"); + memset(line_buf,0, 4096); + if(mountpassword) { + memset(mountpassword,0,64); + } + exit(1); + } else { + if(mountpassword == NULL) { + mountpassword = calloc(65,1); + } + if(mountpassword) { + strncpy(mountpassword,temp_val,64); + got_password = 1; + } + } + } + } + } + fclose(fs); + if(line_buf) { + memset(line_buf,0,4096); + free(line_buf); + } + return 0; } -int parse_options(char * options) +static int get_password_from_file(int file_descript, char * filename) +{ + int rc = 0; + int i; + char c; + + if(mountpassword == NULL) + mountpassword = calloc(65,1); + else + memset(mountpassword, 0, 64); + + if(filename != NULL) { + file_descript = open(filename, O_RDONLY); + if(file_descript < 0) { + printf("cifs.mount failed. %s attempting to open password file %s\n", + strerror(errno),filename); + exit(1); + } + } + /* else file already open and fd provided */ + + for(i=0;i<64;i++) { + rc = read(file_descript,&c,1); + if(rc < 0) { + printf("cifs.mount failed. Error %s reading password file\n",strerror(errno)); + memset(mountpassword,0,64); + if(filename != NULL) + close(file_descript); + exit(1); + } else if(rc == 0) { + if(mountpassword[0] == 0) { + if(verboseflag) + printf("\nWarning: null password used since cifs password file empty"); + } + break; + } else /* read valid character */ { + if((c == 0) || (c == '\n')) { + break; + } else + mountpassword[i] = c; + } + } + if((i == 64) && (verboseflag)) { + printf("\nWarning: password longer than 64 characters specified in cifs password file"); + } + got_password = 1; + if(filename != NULL) { + close(file_descript); + } + + return rc; +} + +static int parse_options(char * options) { char * data; + char * percent_char = 0; char * value = 0; + char * next_keyword = 0; + int rc = 0; if (!options) return 1; + else + data = options; + + if(verboseflag) + printf("\n parsing options: %s", options); - while ((data = strsep(&options, ",")) != NULL) { - if (!*data) - continue; +/* while ((data = strsep(&options, ",")) != NULL) { */ + while(data != NULL) { + /* check if ends with trailing comma */ + if(*data == 0) + break; + + /* format is keyword=value,keyword2=value2,keyword3=value3 etc.) */ + /* data = next keyword */ + /* value = next value ie stuff after equal sign */ + + next_keyword = strchr(data,','); + + /* temporarily null terminate end of keyword=value pair */ + if(next_keyword) + *next_keyword = 0; + + /* if (!*data) + continue; */ + + /* temporarily null terminate keyword to make keyword and value distinct */ if ((value = strchr(data, '=')) != NULL) { - *value++ = '\0'; + *value = '\0'; + value++; } + if (strncmp(data, "user", 4) == 0) { if (!value || !*value) { printf("invalid or missing username\n"); @@ -87,113 +275,142 @@ int parse_options(char * options) } if (strnlen(value, 260) < 260) { got_user=1; - /* BB add check for format user%pass */ - /* if(strchr(username%passw) got_password = 1) */ + percent_char = strchr(value,'%'); + if(percent_char) { + *percent_char = ','; + if(mountpassword == NULL) + mountpassword = calloc(65,1); + if(mountpassword) { + if(got_password) + printf("\ncifs.mount warning - password specified twice\n"); + got_password = 1; + percent_char++; + strncpy(mountpassword, percent_char,64); + /* remove password from username */ + while(*percent_char != 0) { + *percent_char = ','; + percent_char++; + } + } + } } else { printf("username too long\n"); return 1; } - } else if (strncmp(data, "pass", 4) == 0) { - if (!value || !*value) { - if(got_password) { - printf("password specified twice, ignoring second\n"); - } else + } else if (strncmp(data, "pass", 4) == 0) { + if (!value || !*value) { + if(got_password) { + printf("\npassword specified twice, ignoring second\n"); + } else + got_password = 1; + } else if (strnlen(value, 17) < 17) { + if(got_password) + printf("\ncifs.mount warning - password specified twice\n"); got_password = 1; - } else if (strnlen(value, 17) < 17) { - got_password = 1; - } else { - printf("password too long\n"); - return 1; - } - } else if (strncmp(data, "ip", 2) == 0) { - if (!value || !*value) { - printf("target ip address argument missing"); - } else if (strnlen(value, 35) < 35) { - got_ip = 1; - } else { - printf("ip address too long\n"); - return 1; - } - } else if ((strncmp(data, "unc", 3) == 0) + } else { + printf("password too long\n"); + return 1; + } + } else if (strncmp(data, "ip", 2) == 0) { + if (!value || !*value) { + printf("target ip address argument missing"); + } else if (strnlen(value, 35) < 35) { + got_ip = 1; + } else { + printf("ip address too long\n"); + return 1; + } + } else if ((strncmp(data, "unc", 3) == 0) || (strncmp(data, "target", 6) == 0) || (strncmp(data, "path", 4) == 0)) { - if (!value || !*value) { - printf("invalid path to network resource\n"); - return 1; /* needs_arg; */ - } else if(strnlen(value,5) < 5) { - printf("UNC name too short"); - } + if (!value || !*value) { + printf("invalid path to network resource\n"); + return 1; /* needs_arg; */ + } else if(strnlen(value,5) < 5) { + printf("UNC name too short"); + } - if (strnlen(value, 300) < 300) { - got_unc = 1; - if (strncmp(value, "//", 2) == 0) { - if(got_unc) - printf("unc name specified twice, ignoring second\n"); - else - got_unc = 1; - } else if (strncmp(value, "\\\\", 2) != 0) { - printf("UNC Path does not begin with // or \\\\ \n"); + if (strnlen(value, 300) < 300) { + got_unc = 1; + if (strncmp(value, "//", 2) == 0) { + if(got_unc) + printf("unc name specified twice, ignoring second\n"); + else + got_unc = 1; + } else if (strncmp(value, "\\\\", 2) != 0) { + printf("UNC Path does not begin with // or \\\\ \n"); + return 1; + } else { + if(got_unc) + printf("unc name specified twice, ignoring second\n"); + else + got_unc = 1; + } + } else { + printf("CIFS: UNC name too long\n"); return 1; + } + } else if ((strncmp(data, "domain", 3) == 0) + || (strncmp(data, "workgroup", 5) == 0)) { + if (!value || !*value) { + printf("CIFS: invalid domain name\n"); + return 1; /* needs_arg; */ + } + if (strnlen(value, 65) < 65) { + got_domain = 1; } else { - if(got_unc) - printf("unc name specified twice, ignoring second\n"); - else - got_unc = 1; + printf("domain name too long\n"); + return 1; + } + } else if (strncmp(data, "cred", 4) == 0) { + if (value && *value) { + rc = open_cred_file(value); + if(rc) { + printf("error %d opening credential file %s",rc, value); + return 1; + } + } else { + printf("invalid credential file name specified\n"); + return 1; + } + } else if (strncmp(data, "uid", 3) == 0) { + if (value && *value) { + got_uid = 1; + } + } else if (strncmp(data, "gid", 3) == 0) { + if (value && *value) { + got_gid = 1; } - } else { - printf("CIFS: UNC name too long\n"); - return 1; - } - } else if ((strncmp(data, "domain", 3) == 0) - || (strncmp(data, "workgroup", 5) == 0)) { - if (!value || !*value) { - printf("CIFS: invalid domain name\n"); - return 1; /* needs_arg; */ - } - if (strnlen(value, 65) < 65) { - got_domain = 1; - } else { - printf("domain name too long\n"); - return 1; - } - } else if (strncmp(data, "uid", 3) == 0) { - if (value && *value) { - got_uid = 1; - } - } else if (strncmp(data, "gid", 3) == 0) { - if (value && *value) { - got_gid = 1; - } /* fmask and dmask synonyms for people used to smbfs syntax */ - } else if (strcmp(data, "file_mode") == 0 || strcmp(data, "fmask")==0) { - if (!value || !*value) { - printf ("Option '%s' requires a numerical argument\n", data); - return 1; - } + } else if (strcmp(data, "file_mode") == 0 || strcmp(data, "fmask")==0) { + if (!value || !*value) { + printf ("Option '%s' requires a numerical argument\n", data); + return 1; + } - if (value[0] != '0') { - printf ("WARNING: '%s' not expressed in octal.\n", data); - } + if (value[0] != '0') { + printf ("WARNING: '%s' not expressed in octal.\n", data); + } + + if (strcmp (data, "fmask") == 0) { + printf ("WARNING: CIFS mount option 'fmask' is deprecated. Use 'file_mode' instead.\n"); + data = "file_mode"; + } + } else if (strcmp(data, "dir_mode") == 0 || strcmp(data, "dmask")==0) { + if (!value || !*value) { + printf ("Option '%s' requires a numerical argument\n", data); + return 1; + } + + if (value[0] != '0') { + printf ("WARNING: '%s' not expressed in octal.\n", data); + } - if (strcmp (data, "fmask") == 0) { - printf ("WARNING: CIFS mount option 'fmask' is deprecated. Use 'file_mode' instead.\n"); - data = "file_mode"; - } - } else if (strcmp(data, "dir_mode") == 0 || strcmp(data, "dmask")==0) { - if (!value || !*value) { - printf ("Option '%s' requires a numerical argument\n", data); - return 1; - } - - if (value[0] != '0') { - printf ("WARNING: '%s' not expressed in octal.\n", data); - } - - if (strcmp (data, "dmask") == 0) { - printf ("WARNING: CIFS mount option 'dmask' is deprecated. Use 'dir_mode' instead.\n"); - data = "dir_mode"; - } - } /* else if (strnicmp(data, "port", 4) == 0) { + if (strcmp (data, "dmask") == 0) { + printf ("WARNING: CIFS mount option 'dmask' is deprecated. Use 'dir_mode' instead.\n"); + data = "dir_mode"; + } + } /* else if (strnicmp(data, "port", 4) == 0) { if (value && *value) { vol->port = simple_strtoul(value, &value, 0); @@ -214,6 +431,22 @@ int parse_options(char * options) } else printf("CIFS: Unknown mount option %s\n",data); */ + + /* move to next option */ + data = next_keyword+1; + + /* put overwritten equals sign back */ + if(value) { + value--; + *value = '='; + } + + /* put previous overwritten comma back */ + if(next_keyword) + *next_keyword = ','; + else + data = 0; + } return 0; } @@ -226,8 +459,7 @@ char * parse_server(char * unc_name) char * ipaddress_string = NULL; struct hostent * host_entry; struct in_addr server_ipaddr; - int rc,j; - char temp[64]; + int rc; if(length > 1023) { printf("mount error: UNC name too long"); @@ -244,7 +476,6 @@ char * parse_server(char * unc_name) printf("\nMounting the DFS root for domain not implemented yet"); return 0; } else { - /* BB add support for \\\\ not just // */ if(strncmp(unc_name,"//",2) && strncmp(unc_name,"\\\\",2)) { printf("mount error: improperly formatted UNC name."); printf(" %s does not begin with \\\\ or //\n",unc_name); @@ -300,21 +531,19 @@ static struct option longopts[] = { { "rw", 0, 0, 'w' }, { "options", 1, 0, 'o' }, { "types", 1, 0, 't' }, - { "replace", 0, 0, 129 }, - { "after", 0, 0, 130 }, - { "before", 0, 0, 131 }, - { "over", 0, 0, 132 }, - { "move", 0, 0, 133 }, - { "rsize",1, 0, 136 }, - { "wsize",1, 0, 137 }, - { "uid", 1, 0, 138}, - { "gid", 1, 0, 139}, + { "rsize",1, 0, 'R' }, + { "wsize",1, 0, 'W' }, + { "uid", 1, 0, '1'}, + { "gid", 1, 0, '2'}, { "uuid",1,0,'U' }, - { "user",1,0,140}, - { "username",1,0,140}, - { "dom",1,0,141}, - { "domain",1,0,141}, - { "password",1,0,142}, + { "user",1,0,'u'}, + { "username",1,0,'u'}, + { "dom",1,0,'d'}, + { "domain",1,0,'d'}, + { "password",1,0,'p'}, + { "pass",1,0,'p'}, + { "credentials",1,0,'c'}, + { "port",1,0,'P'}, { NULL, 0, 0, 0 } }; @@ -330,13 +559,14 @@ int main(int argc, char ** argv) char * mountpoint; char * options; char * temp; - int rc,i; + int rc; int rsize = 0; int wsize = 0; int nomtab = 0; int uid = 0; int gid = 0; int optlen = 0; + int orgoptlen = 0; struct stat statbuf; struct utsname sysinfo; struct mntent mountent; @@ -354,56 +584,40 @@ int main(int argc, char ** argv) uname(&sysinfo); /* BB add workstation name and domain and pass down */ -/*#ifdef _GNU_SOURCE - printf(" node: %s machine: %s\n", sysinfo.nodename,sysinfo.machine); -#endif*/ - if(argc < 3) - mount_cifs_usage(); + +/* #ifdef _GNU_SOURCE + printf(" node: %s machine: %s sysname %s domain %s\n", sysinfo.nodename,sysinfo.machine,sysinfo.sysname,sysinfo.domainname); +#endif */ + share_name = argv[1]; mountpoint = argv[2]; + /* add sharename in opts string as unc= parm */ while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsU:vVwt:", longopts, NULL)) != -1) { switch (c) { -/* case 'a': - ++mount_all; - break; - case 'f': - ++fake; - break; - case 'F': - ++optfork; - break; */ - case 'h': /* help */ - mount_cifs_usage (); - break; -/* case 'i': - external_allowed = 0; - break; - case 'l': +/* No code to do the following options yet */ +/* case 'l': list_with_volumelabel = 1; break; case 'L': volumelabel = optarg; break; */ - case 'n': - ++nomtab; - break; - case 'o': - if (orgoptions) { - orgoptions = strcat(orgoptions, ","); - orgoptions = strcat(orgoptions,optarg); - } else - orgoptions = strdup(optarg); - break; +/* case 'a': + ++mount_all; + break; */ -/* case 'O': - if (test_opts) - test_opts = xstrconcat3(test_opts, ",", optarg); - else - test_opts = xstrdup(optarg); - break;*/ + case '?': + case 'h': /* help */ + mount_cifs_usage (); + exit(1); + case 'n': + ++nomtab; + break; + case 'o': + orgoptions = strdup(optarg); + break; case 'r': /* mount readonly */ flags |= MS_RDONLY; break; @@ -413,68 +627,78 @@ int main(int argc, char ** argv) case 'v': ++verboseflag; break; -/* case 'V': - printf ("mount: %s\n", version); - exit (0);*/ + case 'V': + printf ("mount.cifs version: %s.%s%s\n", + MOUNT_CIFS_VERSION_MAJOR, + MOUNT_CIFS_VERSION_MINOR, + MOUNT_CIFS_VENDOR_SUFFIX); + if(mountpassword) { + memset(mountpassword,0,64); + } + exit (0); case 'w': flags &= ~MS_RDONLY; break; -/* case 0: - break; - - case 128: - mounttype = MS_BIND; - break; - case 129: - mounttype = MS_REPLACE; - break; - case 130: - mounttype = MS_AFTER; - break; - case 131: - mounttype = MS_BEFORE; - break; - case 132: - mounttype = MS_OVER; - break; - case 133: - mounttype = MS_MOVE; - break; - case 135: - mounttype = (MS_BIND | MS_REC); - break; */ - case 136: + case 'R': rsize = atoi(optarg) ; break; - case 137: + case 'W': wsize = atoi(optarg); break; - case 138: + case '1': uid = atoi(optarg); break; - case 139: + case '2': gid = atoi(optarg); break; - case 140: + case 'u': got_user = 1; user_name = optarg; break; - case 141: + case 'd': domain_name = optarg; break; - case 142: - got_password = 1; - mountpassword = optarg; + case 'p': + if(mountpassword == NULL) + mountpassword = calloc(65,1); + if(mountpassword) { + got_password = 1; + strncpy(mountpassword,optarg,64); + } + break; + case 't': break; - case '?': default: - mount_cifs_usage (); + printf("unknown mount option %c\n",c); + mount_cifs_usage(); + exit(1); } } - /* canonicalize the path in argv[1]? */ + if(argc < 3) + mount_cifs_usage(); + + if (getenv("PASSWD")) { + if(mountpassword == NULL) + mountpassword = calloc(65,1); + if(mountpassword) { + strncpy(mountpassword,getenv("PASSWD"),64); + got_password = 1; + } + } else if (getenv("PASSWD_FD")) { + get_password_from_file(atoi(getenv("PASSWD_FD")),NULL); + } else if (getenv("PASSWD_FILE")) { + get_password_from_file(0, getenv("PASSWD_FILE")); + } + + ipaddr = parse_server(share_name); + + if (orgoptions && parse_options(orgoptions)) + return 1; + + /* BB save off path and pop after mount returns? */ + /* BB canonicalize the path in argv[1]? */ - /* BB save off path and pop after mount returns */ if(chdir(mountpoint)) { printf("mount error: can not change directory into mount target %s\n",mountpoint); } @@ -490,44 +714,26 @@ int main(int argc, char ** argv) } if((getuid() != 0) && (geteuid() == 0)) { - if((statbuf.st_uid == getuid()) && (S_IRWXU == statbuf.st_mode & S_IRWXU)) { + if((statbuf.st_uid == getuid()) && (S_IRWXU == (statbuf.st_mode & S_IRWXU))) { printf("setuid mount allowed\n"); } else { - printf("mount error: permission denied, not superuser and cifs.mount not installed SUID\n"); + printf("mount error: permission denied or not superuser and cifs.mount not installed SUID\n"); return -1; } } - ipaddr = parse_server(share_name); -/* if(share_name == NULL) - return 1; */ - if (orgoptions && parse_options(strdup(orgoptions))) - return 1; - if(got_user == 0) user_name = getusername(); -/* check username for user%password format */ - if(got_password == 0) { - if (getenv("PASSWD")) { - mountpassword = malloc(33); - if(mountpassword) { - strncpy(mountpassword,getenv("PASSWD"),32); - got_password = 1; - } -/* } else if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) { - get_password_file(); - got_password = 1;*/ /* BB add missing function */ - } else { - mountpassword = getpass("Password: "); /* BB obsolete */ - got_password = 1; - } + mountpassword = getpass("Password: "); /* BB obsolete */ + got_password = 1; } /* FIXME launch daemon (handles dfs name resolution and credential change) remember to clear parms and overwrite password field before launching */ if(orgoptions) { optlen = strlen(orgoptions); + orgoptlen = optlen; } else optlen = 0; if(share_name) @@ -560,19 +766,20 @@ int main(int argc, char ** argv) strcat(options,mountpassword); } strncat(options,",ver=",5); - strcat(options,MOUNT_CIFS_VERSION); + strcat(options,MOUNT_CIFS_VERSION_MAJOR); if(orgoptions) { strcat(options,","); strcat(options,orgoptions); } - /* printf("\noptions %s \n",options);*/ + if(verboseflag) + printf("\ncifs.mount kernel mount options %s \n",options); if(mount(share_name, mountpoint, "cifs", flags, options)) { /* remember to kill daemon on error */ switch (errno) { case 0: printf("mount failed but no error number set\n"); - return 0; + break; case ENODEV: printf("mount error: cifs filesystem not supported by the system\n"); break; @@ -580,6 +787,9 @@ int main(int argc, char ** argv) printf("mount error %d = %s\n",errno,strerror(errno)); } printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n"); + if(mountpassword) { + memset(mountpassword,0,64); + } return -1; } else { pmntfile = setmntent(MOUNTED, "a+"); @@ -596,6 +806,20 @@ int main(int argc, char ** argv) printf("could not update mount table\n"); } } + if(mountpassword) { + memset(mountpassword,0,64); + free(mountpassword); + } + + if(options) { + memset(options,0,optlen); + free(options); + } + + if(orgoptions) { + memset(orgoptions,0,orgoptlen); + free(orgoptions); + } return 0; } diff --git a/source3/configure.in b/source3/configure.in index 1121551efc..821ab3a1ea 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -187,7 +187,6 @@ AC_SUBST(CONFIG_LIBS) AC_ARG_ENABLE(debug, [ --enable-debug Turn on compiler debugging information (default=no)], [if eval "test x$enable_debug = xyes"; then - echo "DEBUGGING TURNED ON!!!!" CFLAGS="${CFLAGS} -g" fi]) @@ -1636,9 +1635,8 @@ for i in $LOOK_DIRS ; do save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS -I$i/include" dnl This is here to handle -withval stuff for --with-libiconv - if test x"$ICONV_PATH_SPEC" = "xyes" ; then - LDFLAGS="-L$i/lib" - fi +dnl Perhaps we should always add a -L + LDFLAGS="$LDFLAGS -L$i/lib" LIBS= export LDFLAGS LIBS CPPFLAGS dnl Try to find iconv(3) @@ -1715,7 +1713,7 @@ dnl ]) LIBS="$ic_save_LIBS" if test x"$samba_cv_HAVE_NATIVE_ICONV" = x"yes"; then CPPFLAGS=$save_CPPFLAGS - CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") + LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS if test x"$jm_cv_lib_iconv" != x; then LIBS="$LIBS -l$jm_cv_lib_iconv" @@ -2640,6 +2638,7 @@ if test x"$with_ads_support" != x"no"; then AC_CHECK_FUNC_EXT(krb5_get_permitted_enctypes, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_get_default_in_tkt_etypes, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_free_ktypes, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_free_data_contents, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_principal_get_comp_string, $KRB5_LIBS) LIBS="$LIBS $KRB5_LIBS" @@ -3056,6 +3055,7 @@ samba_cv_TRY_QUOTAS=no samba_cv_RUN_QUOTA_TESTS=auto samba_cv_WITH_SYS_QUOTAS=auto samba_cv_TRY_SYS_QUOTAS=no +samba_cv_SYSQUOTA_FOUND=no; AC_MSG_CHECKING(whether to try disk-quotas support) AC_ARG_WITH(quotas, @@ -3125,6 +3125,11 @@ AC_MSG_CHECKING(whether to try the lib/sysquotas.c interface on ${host_os}) AC_MSG_RESULT(yes) samba_cv_TRY_SYS_QUOTAS=yes samba_cv_RUN_QUOTA_TESTS=yes + samba_cv_SYSQUOTA_FOUND=yes + AC_DEFINE(HAVE_QUOTACTL_LINUX,1,[Whether Linux quota support is available]) + samba_cv_sysquotas_file="lib/sysquotas_linux.c" + AC_DEFINE(HAVE_LINUX_XFS_QUOTAS,1,[Whether Linux xfs quota support is available]) + samba_cv_found_xfs_header=yes ;; *) AC_MSG_RESULT(no) @@ -3137,21 +3142,21 @@ fi # only check for quota stuff if --with-quotas if test x"$samba_cv_RUN_QUOTA_TESTS" != x"no"; then +# some broken header files need this +AC_CHECK_HEADER(asm/types.h,[ + AC_DEFINE(HAVE_ASM_TYPES_H,1,[check for ]) + AC_ADD_INCLUDE() + ]) + # For quotas on Veritas VxFS filesystems AC_CHECK_HEADERS(sys/fs/vx_quota.h) # For sys/quota.h and linux/quota.h AC_CHECK_HEADERS(sys/quota.h) -AC_CHECK_HEADERS(asm/types.h linux/quota.h) - -# For quotas on Linux XFS filesystems -AC_CHECK_HEADERS(linux/xqm.h linux/xfs_fs.h) -AC_CHECK_HEADERS(xfs/libxfs.h xfs/xqm.h xfs/xfs_fs.h) -# For linux > 2.5.56 -AC_CHECK_HEADERS(linux/dqblk_xfs.h) -# if we have struct if_dqblk in we should use it -AC_CACHE_CHECK([for struct if_dqblk in ],samba_cv_HAVE_STRUCT_IF_DQBLK, [ +if test x"$samba_cv_found_xfs_header" != x"yes"; then +# if we have xfs quota support (IRIX) we should use it +AC_CACHE_CHECK([for XFS QUOTA in ],samba_cv_HAVE_SYS_QUOTA_XFS, [ AC_TRY_COMPILE([ #include "confdefs.h" #ifdef HAVE_SYS_TYPES_H @@ -3160,28 +3165,12 @@ AC_TRY_COMPILE([ #ifdef HAVE_ASM_TYPES_H #include #endif -#include -],[struct if_dqblk D;], -samba_cv_HAVE_STRUCT_IF_DQBLK=yes,samba_cv_HAVE_STRUCT_IF_DQBLK=no)]) -if test "$samba_cv_HAVE_STRUCT_IF_DQBLK"x = "yes"x; then - AC_DEFINE(HAVE_STRUCT_IF_DQBLK,1,[struct if_dqblk]) +#include +],[int i = Q_XGETQUOTA;], +samba_cv_HAVE_SYS_QUOTA_XFS=yes,samba_cv_HAVE_SYS_QUOTA_XFS=no)]) +if test "$samba_cv_HAVE_SYS_QUOTA_XFS"x = "yes"x; then + samba_cv_found_xfs_header=yes fi - -# if we have struct mem_dqblk in we should use it -AC_CACHE_CHECK([for struct mem_dqblk in ],samba_cv_HAVE_STRUCT_MEM_DQBLK, [ -AC_TRY_COMPILE([ -#include "confdefs.h" -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_ASM_TYPES_H -#include -#endif -#include -],[struct mem_dqblk D;], -samba_cv_HAVE_STRUCT_MEM_DQBLK=yes,samba_cv_HAVE_STRUCT_MEM_DQBLK=no)]) -if test "$samba_cv_HAVE_STRUCT_MEM_DQBLK"x = "yes"x; then - AC_DEFINE(HAVE_STRUCT_MEM_DQBLK,1,[struct mem_dqblk]) fi # if we have struct dqblk .dqb_fsoftlimit instead of .dqb_isoftlimit on IRIX @@ -3201,7 +3190,6 @@ fi ################## # look for a working quota system -samba_cv_SYSQUOTA_FOUND=no; if test x"$samba_cv_SYSQUOTA_FOUND" != x"yes"; then AC_CACHE_CHECK([for long quotactl(int cmd, char *special, qid_t id, caddr_t addr)],samba_cv_HAVE_QUOTACTL_4A,[ @@ -3212,7 +3200,9 @@ AC_TRY_RUN_STRICT([ #include "${srcdir-.}/tests/sysquotas.c"],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS], samba_cv_HAVE_QUOTACTL_4A=yes,samba_cv_HAVE_QUOTACTL_4A=no,samba_cv_HAVE_QUOTACTL_4A=cross)]) if test x"$samba_cv_HAVE_QUOTACTL_4A" = x"yes"; then - samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_4A,1,[Whether long quotactl(int cmd, char *special, qid_t id, caddr_t addr) is available]) + samba_cv_SYSQUOTA_FOUND=yes; + AC_DEFINE(HAVE_QUOTACTL_4A,1,[Whether long quotactl(int cmd, char *special, qid_t id, caddr_t addr) is available]) + samba_cv_sysquotas_file="lib/sysquotas_4A.c" fi fi @@ -3226,7 +3216,9 @@ AC_TRY_RUN_STRICT([ samba_cv_HAVE_QUOTACTL_4B=yes,samba_cv_HAVE_QUOTACTL_4B=no,samba_cv_HAVE_QUOTACTL_4B=cross)]) if test x"$samba_cv_HAVE_QUOTACTL_4B" = x"yes"; then echo "int quotactl(const char *path, int cmd, int id, char *addr) is not reworked for the new sys_quota api" -# samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_4B,1,[Whether int quotactl(const char *path, int cmd, int id, char *addr) is available]) + samba_cv_SYSQUOTA_FOUND=yes; + AC_DEFINE(HAVE_QUOTACTL_4B,1,[Whether int quotactl(const char *path, int cmd, int id, char *addr) is available]) + samba_cv_sysquotas_file="lib/sysquotas_4B.c" fi fi @@ -3240,7 +3232,9 @@ AC_TRY_RUN_STRICT([ samba_cv_HAVE_QUOTACTL_3=yes,samba_cv_HAVE_QUOTACTL_3=no,samba_cv_HAVE_QUOTACTL_3=cross)]) if test x"$samba_cv_HAVE_QUOTACTL_3" = x"yes"; then echo "CRAY int quotactl (char *spec, int request, char *arg) is NOT reworked for the sys_quota api" -# samba_cv_SYSQUOTA_FOUND=yes;AC_DEFINE(HAVE_QUOTACTL_3,1,[Whether CRAY int quotactl (char *spec, int request, char *arg); is available]) + samba_cv_SYSQUOTA_FOUND=yes; + AC_DEFINE(HAVE_QUOTACTL_3,1,[Whether CRAY int quotactl (char *spec, int request, char *arg); is available]) + samba_cv_sysquotas_file="lib/sysquotas_3.c" fi fi @@ -3299,6 +3293,27 @@ AC_MSG_CHECKING(whether to use the new lib/sysquotas.c interface) fi fi +if test x"$samba_cv_SYSQUOTA_FOUND" != x"no" -a x"$samba_cv_found_xfs_header" = x"yes"; then +AC_CACHE_CHECK([whether the sys_quota interface works with XFS],samba_cv_SYSQUOTA_WORKS_XFS,[ +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch" +AC_TRY_COMPILE([ +#include "confdefs.h" +#define NO_PROTO_H 1 +#define NO_CONFIG_H 1 +#define HAVE_SYS_QUOTAS 1 +#define HAVE_XFS_QUOTAS 1 +#include "${srcdir-.}/lib/sysquotas_xfs.c" +],[],samba_cv_SYSQUOTA_WORKS_XFS=yes,samba_cv_SYSQUOTA_WORKS_XFS=no) +CPPFLAGS="$SAVE_CPPFLAGS" +]) +if test x"$samba_cv_SYSQUOTA_WORKS_XFS" = x"yes"; then + if test x"$samba_cv_WE_USE_SYS_QUOTAS" = x"yes"; then + AC_DEFINE(HAVE_XFS_QUOTAS,1,[Whether xfs quota support is available]) + fi +fi +fi + AC_CACHE_CHECK([whether the old quota support works],samba_cv_QUOTA_WORKS,[ SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch" @@ -4021,9 +4036,15 @@ WINBIND_WINS_NSS="nsswitch/libnss_wins.$SHLIBEXT" WINBIND_NSS_LDSHFLAGS=$LDSHFLAGS case "$host_os" in - *linux*|*freebsd*) + *linux*) WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o" ;; + *freebsd5*) + # FreeBSD winbind client is implemented as a wrapper around + # the Linux version. + WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_freebsd.o \ + nsswitch/winbind_nss_linux.o" + ;; *irix*) # IRIX has differently named shared libraries WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_irix.o" diff --git a/source3/include/printing.h b/source3/include/printing.h index 1d658a0768..bf7c61b251 100644 --- a/source3/include/printing.h +++ b/source3/include/printing.h @@ -21,8 +21,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "includes.h" - /* This file defines the low-level printing system interfaces used by the SAMBA printing subsystem. diff --git a/source3/include/samba_linux_quota.h b/source3/include/samba_linux_quota.h new file mode 100644 index 0000000000..02b3e5169b --- /dev/null +++ b/source3/include/samba_linux_quota.h @@ -0,0 +1,336 @@ +#ifndef _SAMBA_LINUX_QUOTA_H_ +#define _SAMBA_LINUX_QUOTA_H_ +/* + Unix SMB/CIFS implementation. + Copyright (C) Andrew Tridgell 1994-2002 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + This file is needed because Quota support on Linux has + been broken since Linus kernel 2.4.x. It will only get + better (and this file be removed) when all the distributions + ship a glibc with a working quota.h file. This is very + bad. JRA. + + Original file came from Christoph Hellwig . + Massaged into one nasty include file (to stop us having to + add multiple files into Samba just for Linux braindamage) + by JRA. +*/ + +#undef QUOTABLOCK_SIZE + +#ifndef _QUOTAIO_LINUX_V1 +#define _QUOTAIO_LINUX_V1 + +/* + * Headerfile for old quotafile format + */ + +#include + +#define V1_DQBLK_SIZE_BITS 10 +#define V1_DQBLK_SIZE (1 << V1_DQBLK_SIZE_BITS) /* Size of one quota block in bytes in old format */ + +#define V1_DQOFF(__id) ((loff_t) ((__id) * sizeof(struct v1_disk_dqblk))) + +/* Structure of quota on disk */ +struct v1_disk_dqblk { + u_int32_t dqb_bhardlimit; /* absolute limit on disk blks alloc */ + u_int32_t dqb_bsoftlimit; /* preferred limit on disk blks */ + u_int32_t dqb_curblocks; /* current block count */ + u_int32_t dqb_ihardlimit; /* maximum # allocated inodes */ + u_int32_t dqb_isoftlimit; /* preferred limit on inodes */ + u_int32_t dqb_curinodes; /* current # allocated inodes */ + time_t dqb_btime; /* time limit for excessive disk use */ + time_t dqb_itime; /* time limit for excessive files */ +} __attribute__ ((packed)); + +/* Structure used for communication with kernel */ +struct v1_kern_dqblk { + u_int32_t dqb_bhardlimit; /* absolute limit on disk blks alloc */ + u_int32_t dqb_bsoftlimit; /* preferred limit on disk blks */ + u_int32_t dqb_curblocks; /* current block count */ + u_int32_t dqb_ihardlimit; /* maximum # allocated inodes */ + u_int32_t dqb_isoftlimit; /* preferred inode limit */ + u_int32_t dqb_curinodes; /* current # allocated inodes */ + time_t dqb_btime; /* time limit for excessive disk use */ + time_t dqb_itime; /* time limit for excessive files */ +}; + +struct v1_dqstats { + u_int32_t lookups; + u_int32_t drops; + u_int32_t reads; + u_int32_t writes; + u_int32_t cache_hits; + u_int32_t allocated_dquots; + u_int32_t free_dquots; + u_int32_t syncs; +}; + +#ifndef Q_V1_GETQUOTA +#define Q_V1_GETQUOTA 0x300 +#endif +#ifndef Q_V1_SETQUOTA +#define Q_V1_SETQUOTA 0x400 +#endif + +#endif /* _QUOTAIO_LINUX_V1 */ + +/* + * + * Header file for disk format of new quotafile format + * + */ + +#ifndef _QUOTAIO_LINUX_V2 +#define _QUOTAIO_LINUX_V2 + +#include + +#ifndef _QUOTA_LINUX +#define _QUOTA_LINUX + +#include + +typedef u_int32_t qid_t; /* Type in which we store ids in memory */ +typedef u_int64_t qsize_t; /* Type in which we store size limitations */ + +#define MAXQUOTAS 2 +#define USRQUOTA 0 /* element used for user quotas */ +#define GRPQUOTA 1 /* element used for group quotas */ + +/* + * Definitions for the default names of the quotas files. + */ +#define INITQFNAMES { \ + "user", /* USRQUOTA */ \ + "group", /* GRPQUOTA */ \ + "undefined", \ +} + +/* + * Definitions of magics and versions of current quota files + */ +#define INITQMAGICS {\ + 0xd9c01f11, /* USRQUOTA */\ + 0xd9c01927 /* GRPQUOTA */\ +} + +/* Size of blocks in which are counted size limits in generic utility parts */ +#define QUOTABLOCK_BITS 10 +#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS) + +/* Conversion routines from and to quota blocks */ +#define qb2kb(x) ((x) << (QUOTABLOCK_BITS-10)) +#define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10)) +#define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS) + +/* + * Command definitions for the 'quotactl' system call. + * The commands are broken into a main command defined below + * and a subcommand that is used to convey the type of + * quota that is being manipulated (see above). + */ +#define SUBCMDMASK 0x00ff +#define SUBCMDSHIFT 8 +#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK)) + +#define Q_6_5_QUOTAON 0x0100 /* enable quotas */ +#define Q_6_5_QUOTAOFF 0x0200 /* disable quotas */ +#define Q_6_5_SYNC 0x0600 /* sync disk copy of a filesystems quotas */ + +#define Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */ +#define Q_QUOTAON 0x800002 /* turn quotas on */ +#define Q_QUOTAOFF 0x800003 /* turn quotas off */ +#define Q_GETFMT 0x800004 /* get quota format used on given filesystem */ +#define Q_GETINFO 0x800005 /* get information about quota files */ +#define Q_SETINFO 0x800006 /* set information about quota files */ +#define Q_GETQUOTA 0x800007 /* get user quota structure */ +#define Q_SETQUOTA 0x800008 /* set user quota structure */ + +/* + * Quota structure used for communication with userspace via quotactl + * Following flags are used to specify which fields are valid + */ +#define QIF_BLIMITS 1 +#define QIF_SPACE 2 +#define QIF_ILIMITS 4 +#define QIF_INODES 8 +#define QIF_BTIME 16 +#define QIF_ITIME 32 +#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS) +#define QIF_USAGE (QIF_SPACE | QIF_INODES) +#define QIF_TIMES (QIF_BTIME | QIF_ITIME) +#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES) + +struct if_dqblk { + u_int64_t dqb_bhardlimit; + u_int64_t dqb_bsoftlimit; + u_int64_t dqb_curspace; + u_int64_t dqb_ihardlimit; + u_int64_t dqb_isoftlimit; + u_int64_t dqb_curinodes; + u_int64_t dqb_btime; + u_int64_t dqb_itime; + u_int32_t dqb_valid; +}; + +/* + * Structure used for setting quota information about file via quotactl + * Following flags are used to specify which fields are valid + */ +#define IIF_BGRACE 1 +#define IIF_IGRACE 2 +#define IIF_FLAGS 4 +#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS) + +struct if_dqinfo { + u_int64_t dqi_bgrace; + u_int64_t dqi_igrace; + u_int32_t dqi_flags; + u_int32_t dqi_valid; +}; + +/* Quota format identifiers */ +#define QFMT_VFS_OLD 1 +#define QFMT_VFS_V0 2 + +/* Flags supported by kernel */ +#define V1_DQF_RSQUASH 1 + +/* Ioctl for getting quota size */ +#include +#ifndef FIOQSIZE + #if defined(__alpha__) || defined(__powerpc__) || defined(__sh__) || defined(__sparc__) || defined(__sparc64__) + #define FIOQSIZE _IOR('f', 128, loff_t) + #elif defined(__arm__) || defined(__mc68000__) || defined(__s390__) + #define FIOQSIZE 0x545E + #elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__ia64__) || defined(__parisc__) || defined(__cris__) || defined(__hppa__) + #define FIOQSIZE 0x5460 + #elif defined(__mips__) || defined(__mips64__) + #define FIOQSIZE 0x6667 + #endif +#endif + +long quotactl __P((int, const char *, qid_t, caddr_t)); + +#endif /* _QUOTA_LINUX */ + +#define V2_DQINFOOFF sizeof(struct v2_disk_dqheader) /* Offset of info header in file */ +#define V2_DQBLKSIZE_BITS 10 +#define V2_DQBLKSIZE (1 << V2_DQBLKSIZE_BITS) /* Size of block with quota structures */ +#define V2_DQTREEOFF 1 /* Offset of tree in file in blOcks */ +#define V2_DQTREEDEPTH 4 /* Depth of quota tree */ +#define V2_DQSTRINBLK ((V2_DQBLKSIZE - sizeof(struct v2_disk_dqdbheader)) / sizeof(struct v2_disk_dqblk)) /* Number of entries in one blocks */ +#define V2_GETIDINDEX(id, depth) (((id) >> ((V2_DQTREEDEPTH-(depth)-1)*8)) & 0xff) +#define V2_GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)(buf)) + sizeof(struct v2_disk_dqdbheader))) +#define INIT_V2_VERSIONS { 0, 0} + +struct v2_disk_dqheader { + u_int32_t dqh_magic; /* Magic number identifying file */ + u_int32_t dqh_version; /* File version */ +} __attribute__ ((packed)); + +/* Flags for version specific files */ +#define V2_DQF_MASK 0x0000 /* Mask for all valid ondisk flags */ + +/* Header with type and version specific information */ +struct v2_disk_dqinfo { + u_int32_t dqi_bgrace; /* Time before block soft limit becomes hard limit */ + u_int32_t dqi_igrace; /* Time before inode soft limit becomes hard limit */ + u_int32_t dqi_flags; /* Flags for quotafile (DQF_*) */ + u_int32_t dqi_blocks; /* Number of blocks in file */ + u_int32_t dqi_free_blk; /* Number of first free block in the list */ + u_int32_t dqi_free_entry; /* Number of block with at least one free entry */ +} __attribute__ ((packed)); + +/* + * Structure of header of block with quota structures. It is padded to 16 bytes so + * there will be space for exactly 18 quota-entries in a block + */ +struct v2_disk_dqdbheader { + u_int32_t dqdh_next_free; /* Number of next block with free entry */ + u_int32_t dqdh_prev_free; /* Number of previous block with free entry */ + u_int16_t dqdh_entries; /* Number of valid entries in block */ + u_int16_t dqdh_pad1; + u_int32_t dqdh_pad2; +} __attribute__ ((packed)); + +/* Structure of quota for one user on disk */ +struct v2_disk_dqblk { + u_int32_t dqb_id; /* id this quota applies to */ + u_int32_t dqb_ihardlimit; /* absolute limit on allocated inodes */ + u_int32_t dqb_isoftlimit; /* preferred inode limit */ + u_int32_t dqb_curinodes; /* current # allocated inodes */ + u_int32_t dqb_bhardlimit; /* absolute limit on disk space (in QUOTABLOCK_SIZE) */ + u_int32_t dqb_bsoftlimit; /* preferred limit on disk space (in QUOTABLOCK_SIZE) */ + u_int64_t dqb_curspace; /* current space occupied (in bytes) */ + u_int64_t dqb_btime; /* time limit for excessive disk use */ + u_int64_t dqb_itime; /* time limit for excessive inode use */ +} __attribute__ ((packed)); + +/* Structure of quota for communication with kernel */ +struct v2_kern_dqblk { + unsigned int dqb_ihardlimit; + unsigned int dqb_isoftlimit; + unsigned int dqb_curinodes; + unsigned int dqb_bhardlimit; + unsigned int dqb_bsoftlimit; + qsize_t dqb_curspace; + time_t dqb_btime; + time_t dqb_itime; +}; + +/* Structure of quotafile info for communication with kernel */ +struct v2_kern_dqinfo { + unsigned int dqi_bgrace; + unsigned int dqi_igrace; + unsigned int dqi_flags; + unsigned int dqi_blocks; + unsigned int dqi_free_blk; + unsigned int dqi_free_entry; +}; + +/* Structure with gathered statistics from kernel */ +struct v2_dqstats { + u_int32_t lookups; + u_int32_t drops; + u_int32_t reads; + u_int32_t writes; + u_int32_t cache_hits; + u_int32_t allocated_dquots; + u_int32_t free_dquots; + u_int32_t syncs; + u_int32_t version; +}; + +#ifndef Q_V2_GETQUOTA +#define Q_V2_GETQUOTA 0x0D00 +#endif +#ifndef Q_V2_SETQUOTA +#define Q_V2_SETQUOTA 0x0E00 +#endif + +#endif /* _QUOTAIO_LINUX_V2 */ + +#ifndef QUOTABLOCK_SIZE +#define QUOTABLOCK_SIZE 1024 +#endif + +#endif /* _SAMBA_LINUX_QUOTA_H_ */ diff --git a/source3/include/samba_xfs_quota.h b/source3/include/samba_xfs_quota.h new file mode 100644 index 0000000000..1db435064a --- /dev/null +++ b/source3/include/samba_xfs_quota.h @@ -0,0 +1,165 @@ +#ifndef _SAMBA_LINUX_XFS_H_ +#define _SAMBA_LINUX_XFS_H_ + +#ifndef _QUOTAIO_LINUX_XFS +#define _QUOTAIO_LINUX_XFS + +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include + +#define XQM_CMD(cmd) ( ('X'<<8)+(cmd) ) +#define IS_XQM_CMD(cmd) ( ((int)(cmd)>>8) == 'X' ) + +/* + * Disk quota - quotactl(2) commands for XFS Quota Manager (XQM). + */ +#define Q_XQUOTAON XQM_CMD(0x1) /* enable quota accounting/enforcement */ +#define Q_XQUOTAOFF XQM_CMD(0x2) /* disable quota accounting/enforcement */ +#define Q_XGETQUOTA XQM_CMD(0x3) /* get disk limits & usage */ +#define Q_XSETQLIM XQM_CMD(0x4) /* set disk limits only */ +#define Q_XGETQSTAT XQM_CMD(0x5) /* returns fs_quota_stat_t struct */ +#define Q_XQUOTARM XQM_CMD(0x6) /* free quota files' space */ + +/* + * fs_disk_quota structure: + * + * This contains the current quota information regarding a user/proj/group. + * It is 64-bit aligned, and all the blk units are in BBs (Basic Blocks) of + * 512 bytes. + */ +#define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */ +typedef struct fs_disk_quota { + u_int8_t d_version; /* version of this structure */ + u_int8_t d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */ + u_int16_t d_fieldmask; /* field specifier */ + u_int32_t d_id; /* user, project, or group ID */ + u_int64_t d_blk_hardlimit; /* absolute limit on disk blks */ + u_int64_t d_blk_softlimit; /* preferred limit on disk blks */ + u_int64_t d_ino_hardlimit; /* maximum # allocated inodes */ + u_int64_t d_ino_softlimit; /* preferred inode limit */ + u_int64_t d_bcount; /* # disk blocks owned by the user */ + u_int64_t d_icount; /* # inodes owned by the user */ + int32_t d_itimer; /* zero if within inode limits */ + /* if not, we refuse service */ + int32_t d_btimer; /* similar to above; for disk blocks */ + u_int16_t d_iwarns; /* # warnings issued wrt num inodes */ + u_int16_t d_bwarns; /* # warnings issued wrt disk blocks */ + int32_t d_padding2; /* padding2 - for future use */ + u_int64_t d_rtb_hardlimit; /* absolute limit on realtime blks */ + u_int64_t d_rtb_softlimit; /* preferred limit on RT disk blks */ + u_int64_t d_rtbcount; /* # realtime blocks owned */ + int32_t d_rtbtimer; /* similar to above; for RT disk blks */ + u_int16_t d_rtbwarns; /* # warnings issued wrt RT disk blks */ + int16_t d_padding3; /* padding3 - for future use */ + char d_padding4[8]; /* yet more padding */ +} fs_disk_quota_t; + +/* + * These fields are sent to Q_XSETQLIM to specify fields that need to change. + */ +#define FS_DQ_ISOFT (1<<0) +#define FS_DQ_IHARD (1<<1) +#define FS_DQ_BSOFT (1<<2) +#define FS_DQ_BHARD (1<<3) +#define FS_DQ_RTBSOFT (1<<4) +#define FS_DQ_RTBHARD (1<<5) +#define FS_DQ_LIMIT_MASK (FS_DQ_ISOFT | FS_DQ_IHARD | FS_DQ_BSOFT | \ + FS_DQ_BHARD | FS_DQ_RTBSOFT | FS_DQ_RTBHARD) +/* + * These timers can only be set in super user's dquot. For others, timers are + * automatically started and stopped. Superusers timer values set the limits + * for the rest. In case these values are zero, the DQ_{F,B}TIMELIMIT values + * defined below are used. + * These values also apply only to the d_fieldmask field for Q_XSETQLIM. + */ +#define FS_DQ_BTIMER (1<<6) +#define FS_DQ_ITIMER (1<<7) +#define FS_DQ_RTBTIMER (1<<8) +#define FS_DQ_TIMER_MASK (FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER) + +/* + * The following constants define the default amount of time given a user + * before the soft limits are treated as hard limits (usually resulting + * in an allocation failure). These may be modified by the quotactl(2) + * system call with the Q_XSETQLIM command. + */ +#define DQ_FTIMELIMIT (7 * 24*60*60) /* 1 week */ +#define DQ_BTIMELIMIT (7 * 24*60*60) /* 1 week */ + +/* + * Various flags related to quotactl(2). Only relevant to XFS filesystems. + */ +#define XFS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */ +#define XFS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */ +#define XFS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */ +#define XFS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */ + +#define XFS_USER_QUOTA (1<<0) /* user quota type */ +#define XFS_PROJ_QUOTA (1<<1) /* (IRIX) project quota type */ +#define XFS_GROUP_QUOTA (1<<2) /* group quota type */ + +/* + * fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system. + * Provides a centralized way to get meta infomation about the quota subsystem. + * eg. space taken up for user and group quotas, number of dquots currently + * incore. + */ +#define FS_QSTAT_VERSION 1 /* fs_quota_stat.qs_version */ + +/* + * Some basic infomation about 'quota files'. + */ +typedef struct fs_qfilestat { + u_int64_t qfs_ino; /* inode number */ + u_int64_t qfs_nblks; /* number of BBs 512-byte-blks */ + u_int32_t qfs_nextents; /* number of extents */ +} fs_qfilestat_t; + +typedef struct fs_quota_stat { + u_int8_t qs_version; /* version number for future changes */ + u_int16_t qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */ + u_int8_t qs_pad; /* unused */ + fs_qfilestat_t qs_uquota; /* user quota storage information */ + fs_qfilestat_t qs_gquota; /* group quota storage information */ + u_int32_t qs_incoredqs; /* number of dquots incore */ + int32_t qs_btimelimit; /* limit for blks timer */ + int32_t qs_itimelimit; /* limit for inodes timer */ + int32_t qs_rtbtimelimit; /* limit for rt blks timer */ + u_int16_t qs_bwarnlimit; /* limit for num warnings */ + u_int16_t qs_iwarnlimit; /* limit for num warnings */ +} fs_quota_stat_t; + +#endif /* _QUOTAIO_LINUX_XFS */ + +#endif /* _SAMBA_LINUX_XFS_H_ */ diff --git a/source3/include/sysquotas.h b/source3/include/sysquotas.h index b803e6277a..bfb9466b39 100644 --- a/source3/include/sysquotas.h +++ b/source3/include/sysquotas.h @@ -23,150 +23,6 @@ #ifdef HAVE_SYS_QUOTAS -/* Sometimes we need this on linux for linux/quota.h */ -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_ASM_TYPES_H -#include -#endif - -/* - * This shouldn't be neccessary - it should be /usr/include/sys/quota.h - * Unfortunately, RH7.1 ships with a different quota system using struct mem_dqblk - * rather than the struct dqblk defined in /usr/include/sys/quota.h. - * This means we must include linux/quota.h to have a hope of working on - * RH7.1 systems. And it also means this breaks if the kernel is upgraded - * to a Linus 2.4.x (where x > the minor number shipped with RH7.1) until - * Linus synchronises with the AC patches. Sometimes I *hate* Linux :-). JRA. - */ -#ifdef HAVE_LINUX_QUOTA_H -#include -#elif defined(HAVE_SYS_QUOTA_H) -#include -#endif - -#if defined(HAVE_STRUCT_IF_DQBLK) -# define SYS_DQBLK if_dqblk -# define dqb_curblocks dqb_curspace/bsize -#elif defined(HAVE_STRUCT_MEM_DQBLK) -# define SYS_DQBLK mem_dqblk -# define dqb_curblocks dqb_curspace/bsize -#else /* STRUCT_DQBLK */ -# define SYS_DQBLK dqblk -#endif - -#ifndef Q_SETQLIM -#define Q_SETQLIM Q_SETQUOTA -#endif - -/********************************************* - check for XFS QUOTA MANAGER - *********************************************/ -/* on linux */ -#ifdef HAVE_LINUX_XQM_H -# include -# define HAVE_XFS_QUOTA -#else -# ifdef HAVE_XFS_XQM_H -# include -# define HAVE_XFS_QUOTA -# else -# ifdef HAVE_LINUX_DQBLK_XFS_H -# include -# define HAVE_XFS_QUOTA -# endif -# endif -#endif -/* on IRIX */ -#ifdef Q_XGETQUOTA -# ifndef HAVE_XFS_QUOTA -# define HAVE_XFS_QUOTA -# ifndef Q_XQUOTAON -# define Q_XQUOTAON Q_QUOTAON -# endif /* Q_XQUOTAON */ -# ifndef Q_XQUOTAOFF -# define Q_XQUOTAOFF Q_QUOTAOFF -# endif /* Q_XQUOTAOFF */ -# ifndef Q_XGETQSTAT -# define Q_XGETQSTAT Q_GETQSTAT -# endif /* Q_XGETQSTAT */ -# endif /* HAVE_XFS_QUOTA */ -#endif /* Q_XGETQUOTA */ - -#ifdef HAVE_XFS_QUOTA -/* Linux has BBSIZE in - * or - * IRIX has BBSIZE in - */ -#ifdef HAVE_LINUX_XFS_FS_H -#include -#elif defined(HAVE_XFS_XFS_FS_H) -#include -#endif /* *_XFS_FS_H */ - -#ifndef BBSHIFT -#define BBSHIFT 9 -#endif /* BBSHIFT */ -#ifndef BBSIZE -#define BBSIZE (1< #define HAVE_MNTENT 1 @@ -178,10 +34,6 @@ #endif /* HAVE_SYS_QUOTAS */ -#ifndef QUOTABLOCK_SIZE -#define QUOTABLOCK_SIZE 1024 -#endif - /************************************************** Some stuff for the sys_quota api. **************************************************/ @@ -217,4 +69,8 @@ typedef struct _SMB_DISK_QUOTA { uint32 qflags; } SMB_DISK_QUOTA; +#ifndef QUOTABLOCK_SIZE +#define QUOTABLOCK_SIZE 1024 +#endif + #endif /*_SYSQUOTAS_H */ diff --git a/source3/intl/lang_tdb.c b/source3/intl/lang_tdb.c index b98e5734cb..fe2ad5b2fc 100644 --- a/source3/intl/lang_tdb.c +++ b/source3/intl/lang_tdb.c @@ -176,7 +176,8 @@ BOOL lang_tdb_init(const char *lang) const char *lang_msg(const char *msgid) { TDB_DATA key, data; - char *p, *q, *msgid_quoted; + const char *p; + char *q, *msgid_quoted; int count; lang_tdb_init(NULL); diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 7903dfd3f6..1c6058a43e 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -192,7 +192,7 @@ static size_t convert_string_internal(charset_t from, charset_t to, i_len=srclen; o_len=destlen; - retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len); + retval = smb_iconv(descriptor, (char **)&inbuf, &i_len, &outbuf, &o_len); if(retval==(size_t)-1) { const char *reason="unknown error"; switch(errno) { @@ -426,7 +426,7 @@ convert: i_len = srclen; o_len = destlen; retval = smb_iconv(descriptor, - &inbuf, &i_len, + (char **)&inbuf, &i_len, &outbuf, &o_len); if(retval == (size_t)-1) { const char *reason="unknown error"; diff --git a/source3/lib/sysquotas.c b/source3/lib/sysquotas.c index 3223ecb580..6883444e00 100644 --- a/source3/lib/sysquotas.c +++ b/source3/lib/sysquotas.c @@ -24,255 +24,6 @@ #ifdef HAVE_SYS_QUOTAS #if defined(HAVE_QUOTACTL_4A) -/* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */ -/* this is used by: linux,HPUX,IRIX */ - -/**************************************************************************** - Abstract out the old and new Linux quota get calls. -****************************************************************************/ -static int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) -{ - int ret = -1; - uint32 qflags = 0; - struct SYS_DQBLK D; - SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; - - if (!path||!bdev||!dp) - smb_panic("sys_get_vfs_quota: called with NULL pointer"); - - ZERO_STRUCT(D); - ZERO_STRUCT(*dp); - dp->qtype = qtype; - - switch (qtype) { - case SMB_USER_QUOTA_TYPE: - if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))) { - return ret; - } - - if ((D.dqb_curblocks==0)&& - (D.dqb_bsoftlimit==0)&& - (D.dqb_bhardlimit==0)) { - /* the upper layer functions don't want empty quota records...*/ - return -1; - } - - break; -#ifdef HAVE_GROUP_QUOTA - case SMB_GROUP_QUOTA_TYPE: - if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))) { - return ret; - } - - if ((D.dqb_curblocks==0)&& - (D.dqb_bsoftlimit==0)&& - (D.dqb_bhardlimit==0)) { - /* the upper layer functions don't want empty quota records...*/ - return -1; - } - - break; -#endif /* HAVE_GROUP_QUOTA */ - case SMB_USER_FS_QUOTA_TYPE: - id.uid = getuid(); - - if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))==0) { - qflags |= QUOTAS_DENY_DISK; - } - - ret = 0; - break; -#ifdef HAVE_GROUP_QUOTA - case SMB_GROUP_FS_QUOTA_TYPE: - id.gid = getgid(); - - if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))==0) { - qflags |= QUOTAS_DENY_DISK; - } - - ret = 0; - break; -#endif /* HAVE_GROUP_QUOTA */ - default: - errno = ENOSYS; - return -1; - } - - dp->bsize = bsize; - dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; - dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; - dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; - dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; - dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; - dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks; - - - dp->qflags = qflags; - - return ret; -} - -/**************************************************************************** - Abstract out the old and new Linux quota set calls. -****************************************************************************/ - -static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) -{ - int ret = -1; - uint32 qflags = 0; - uint32 oldqflags = 0; - struct SYS_DQBLK D; - SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; - - if (!path||!bdev||!dp) - smb_panic("sys_set_vfs_quota: called with NULL pointer"); - - ZERO_STRUCT(D); - - if (bsize == dp->bsize) { - D.dqb_bsoftlimit = dp->softlimit; - D.dqb_bhardlimit = dp->hardlimit; - D.dqb_ihardlimit = dp->ihardlimit; - D.dqb_isoftlimit = dp->isoftlimit; - } else { - D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize; - D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize; - D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize; - D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize; - } - - qflags = dp->qflags; - - switch (qtype) { - case SMB_USER_QUOTA_TYPE: - ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D); - break; -#ifdef HAVE_GROUP_QUOTA - case SMB_GROUP_QUOTA_TYPE: - ret = quotactl(QCMD(Q_SETQLIM,GRPQUOTA), bdev, id.gid, (CADDR_T)&D); - break; -#endif /* HAVE_GROUP_QUOTA */ - case SMB_USER_FS_QUOTA_TYPE: - /* this stuff didn't work as it should: - * switching on/off quota via quotactl() - * didn't work! - * So we just return 0 - * --metze - * - * On HPUX we didn't have the mount path, - * we need to fix sys_path_to_bdev() - * - */ -#if 0 - id.uid = getuid(); - - ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D); - - if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) { - if (ret == 0) { - char *quota_file = NULL; - - asprintf("a_file,"/%s/%s%s",path, QUOTAFILENAME,USERQUOTAFILE_EXTENSION); - if (quota_file == NULL) { - DEBUG(0,("asprintf() failed!\n")); - errno = ENOMEM; - return -1; - } - - ret = quotactl(QCMD(Q_QUOTAON,USRQUOTA), bdev, -1,(CADDR_T)quota_file); - } else { - ret = 0; - } - } else { - if (ret != 0) { - /* turn off */ - ret = quotactl(QCMD(Q_QUOTAOFF,USRQUOTA), bdev, -1, (CADDR_T)0); - } else { - ret = 0; - } - } - - DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", - ret,errno,strerror(errno),id.uid,bdev)); -#else - id.uid = getuid(); - - if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))==0) { - oldqflags |= QUOTAS_DENY_DISK; - } - - if (oldqflags == qflags) { - ret = 0; - } else { - ret = -1; - } -#endif - break; -#ifdef HAVE_GROUP_QUOTA - case SMB_GROUP_FS_QUOTA_TYPE: - /* this stuff didn't work as it should: - * switching on/off quota via quotactl() - * didn't work! - * So we just return 0 - * --metze - * - * On HPUX we didn't have the mount path, - * we need to fix sys_path_to_bdev() - * - */ -#if 0 - id.gid = getgid(); - - ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (CADDR_T)&D); - - if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) { - if (ret == 0) { - char *quota_file = NULL; - - asprintf("a_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION); - if (quota_file == NULL) { - DEBUG(0,("asprintf() failed!\n")); - errno = ENOMEM; - return -1; - } - - ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), bdev, -1,(CADDR_T)quota_file); - } else { - ret = 0; - } - } else { - if (ret != 0) { - /* turn off */ - ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), bdev, -1, (CADDR_T)0); - } else { - ret = 0; - } - } - - DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", - ret,errno,strerror(errno),id.gid,bdev)); -#else - id.gid = getgid(); - - if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))==0) { - oldqflags |= QUOTAS_DENY_DISK; - } - - if (oldqflags == qflags) { - ret = 0; - } else { - ret = -1; - } -#endif - break; -#endif /* HAVE_GROUP_QUOTA */ - default: - errno = ENOSYS; - return -1; - } - - return ret; -} /*#endif HAVE_QUOTACTL_4A */ #elif defined(HAVE_QUOTACTL_4B) @@ -287,30 +38,6 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ /* #endif HAVE_QUOTACTL_3 */ #else /* NO_QUOTACTL_USED */ -static int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) -{ - int ret = -1; - - if (!path||!bdev||!dp) - smb_panic("sys_get_vfs_quota: called with NULL pointer"); - - errno = ENOSYS; - - return ret; -} - -static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) -{ - int ret = -1; - - if (!path||!bdev||!dp) - smb_panic("sys_set_vfs_quota: called with NULL pointer"); - - errno = ENOSYS; - - return ret; -} - #endif /* NO_QUOTACTL_USED */ #ifdef HAVE_MNTENT @@ -434,262 +161,6 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char } #endif - -/********************************************************* - if we have XFS QUOTAS we should use them - *********************************************************/ -#ifdef HAVE_XFS_QUOTA -/**************************************************************************** - Abstract out the XFS Quota Manager quota get call. -****************************************************************************/ -static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) -{ - int ret = -1; - uint32 qflags = 0; - SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE; - struct fs_disk_quota D; - struct fs_quota_stat F; - ZERO_STRUCT(D); - ZERO_STRUCT(F); - - if (!bdev||!dp) - smb_panic("sys_get_xfs_quota: called with NULL pointer"); - - ZERO_STRUCT(*dp); - dp->qtype = qtype; - - switch (qtype) { - case SMB_USER_QUOTA_TYPE: - if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))) - return ret; - break; -#ifdef HAVE_GROUP_QUOTA - case SMB_GROUP_QUOTA_TYPE: - if ((ret=quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))) - return ret; - break; -#endif /* HAVE_GROUP_QUOTA */ - case SMB_USER_FS_QUOTA_TYPE: - quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F); - - if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) { - qflags |= QUOTAS_DENY_DISK; - } - else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) { - qflags |= QUOTAS_ENABLED; - } - - ret = 0; - - break; -#ifdef HAVE_GROUP_QUOTA - case SMB_GROUP_FS_QUOTA_TYPE: - quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (CADDR_T)&F); - - if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) { - qflags |= QUOTAS_DENY_DISK; - } - else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) { - qflags |= QUOTAS_ENABLED; - } - - ret = 0; - - break; -#endif /* HAVE_GROUP_QUOTA */ - default: - errno = ENOSYS; - return -1; - } - - dp->bsize = bsize; - dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit; - dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit; - dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit; - dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit; - dp->curinodes = (SMB_BIG_UINT)D.d_icount; - dp->curblocks = (SMB_BIG_UINT)D.d_bcount; - dp->qflags = qflags; - - return ret; -} - -/**************************************************************************** - Abstract out the XFS Quota Manager quota set call. -****************************************************************************/ -static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) -{ - int ret = -1; - uint32 qflags = 0; - SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE; - struct fs_disk_quota D; - struct fs_quota_stat F; - int q_on = 0; - int q_off = 0; - ZERO_STRUCT(D); - ZERO_STRUCT(F); - - if (!bdev||!dp) - smb_panic("sys_set_xfs_quota: called with NULL pointer"); - - if (bsize == dp->bsize) { - D.d_blk_softlimit = dp->softlimit; - D.d_blk_hardlimit = dp->hardlimit; - D.d_ino_hardlimit = dp->ihardlimit; - D.d_ino_softlimit = dp->isoftlimit; - } else { - D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize; - D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize; - D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize; - D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize; - } - - qflags = dp->qflags; - - switch (qtype) { - case SMB_USER_QUOTA_TYPE: - D.d_fieldmask |= FS_DQ_LIMIT_MASK; - ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D); - break; -#ifdef HAVE_GROUP_QUOTA - case SMB_GROUP_QUOTA_TYPE: - D.d_fieldmask |= FS_DQ_LIMIT_MASK; - ret = quotactl(QCMD(Q_XSETQLIM,GRPQUOTA), bdev, id.gid, (CADDR_T)&D); - break; -#endif /* HAVE_GROUP_QUOTA */ - case SMB_USER_FS_QUOTA_TYPE: - quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F); - - if (qflags & QUOTAS_DENY_DISK) { - if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD)) - q_on |= XFS_QUOTA_UDQ_ENFD; - if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) - q_on |= XFS_QUOTA_UDQ_ACCT; - - if (q_on != 0) { - ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (CADDR_T)&q_on); - } else { - ret = 0; - } - - } else if (qflags & QUOTAS_ENABLED) { - if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) - q_off |= XFS_QUOTA_UDQ_ENFD; - - if (q_off != 0) { - ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (CADDR_T)&q_off); - } else { - ret = 0; - } - - if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) - q_on |= XFS_QUOTA_UDQ_ACCT; - - if (q_on != 0) { - ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (CADDR_T)&q_on); - } else { - ret = 0; - } - } else { -#if 0 - /* Switch on XFS_QUOTA_UDQ_ACCT didn't work! - * only swittching off XFS_QUOTA_UDQ_ACCT work - */ - if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) - q_off |= XFS_QUOTA_UDQ_ENFD; - if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) - q_off |= XFS_QUOTA_UDQ_ACCT; - - if (q_off !=0) { - ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (CADDR_T)&q_off); - } else { - ret = 0; - } -#else - ret = -1; -#endif - } - - break; -#ifdef HAVE_GROUP_QUOTA - case SMB_GROUP_FS_QUOTA_TYPE: - quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (CADDR_T)&F); - - if (qflags & QUOTAS_DENY_DISK) { - if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD)) - q_on |= XFS_QUOTA_UDQ_ENFD; - if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) - q_on |= XFS_QUOTA_UDQ_ACCT; - - if (q_on != 0) { - ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (CADDR_T)&q_on); - } else { - ret = 0; - } - - } else if (qflags & QUOTAS_ENABLED) { - if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) - q_off |= XFS_QUOTA_UDQ_ENFD; - - if (q_off != 0) { - ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (CADDR_T)&q_off); - } else { - ret = 0; - } - - if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) - q_on |= XFS_QUOTA_UDQ_ACCT; - - if (q_on != 0) { - ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (CADDR_T)&q_on); - } else { - ret = 0; - } - } else { -#if 0 - /* Switch on XFS_QUOTA_UDQ_ACCT didn't work! - * only swittching off XFS_QUOTA_UDQ_ACCT work - */ - if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) - q_off |= XFS_QUOTA_UDQ_ENFD; - if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) - q_off |= XFS_QUOTA_UDQ_ACCT; - - if (q_off !=0) { - ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (CADDR_T)&q_off); - } else { - ret = 0; - } -#else - ret = -1; -#endif - } - - break; -#endif /* HAVE_GROUP_QUOTA */ - default: - errno = ENOSYS; - return -1; - } - - return ret; -} -#endif /* HAVE_XFS_QUOTA */ - - - - - - - - - - - - - - - /********************************************************************* Now the list of all filesystem specific quota systems we have found **********************************************************************/ diff --git a/source3/lib/sysquotas_4A.c b/source3/lib/sysquotas_4A.c new file mode 100644 index 0000000000..66b367f099 --- /dev/null +++ b/source3/lib/sysquotas_4A.c @@ -0,0 +1,318 @@ +/* + Unix SMB/CIFS implementation. + System QUOTA function wrappers for QUOTACTL_4A + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include "includes.h" + +#ifdef HAVE_QUOTACTL_4A +/* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */ +/* this is used by: HPUX,IRIX */ + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_ASM_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_QUOTA_H +#include +#endif + +#ifndef Q_SETQLIM +#define Q_SETQLIM Q_SETQUOTA +#endif + +#ifndef QCMD +#define QCMD(x,y) x +#endif + +#ifndef QCMD +#define QCMD(x,y) x +#endif + +#ifdef GRPQUOTA +#define HAVE_GROUP_QUOTA +#endif + +#ifndef QUOTABLOCK_SIZE +#define QUOTABLOCK_SIZE DEV_BSIZE +#endif + +#ifdef HAVE_DQB_FSOFTLIMIT +#define dqb_isoftlimit dqb_fsoftlimit +#define dqb_ihardlimit dqb_fhardlimit +#define dqb_curinodes dqb_curfiles +#endif + +#ifdef INITQFNAMES +#define USERQUOTAFILE_EXTENSION ".user" +#else +#define USERQUOTAFILE_EXTENSION "" +#endif + +#if !defined(QUOTAFILENAME) && defined(QFILENAME) +#define QUOTAFILENAME QFILENAME +#endif + +/**************************************************************************** + Abstract out the quotactl_4A get calls. +****************************************************************************/ +int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + uint32 qflags = 0; + struct dqblk D; + SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + + ZERO_STRUCT(D); + ZERO_STRUCT(*dp); + dp->qtype = qtype; + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))&&errno != EDQUOT) { + return ret; + } + + if ((D.dqb_curblocks==0)&& + (D.dqb_bsoftlimit==0)&& + (D.dqb_bhardlimit==0)) { + /* the upper layer functions don't want empty quota records...*/ + return -1; + } + + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))&&errno != EDQUOT) { + return ret; + } + + if ((D.dqb_curblocks==0)&& + (D.dqb_bsoftlimit==0)&& + (D.dqb_bhardlimit==0)) { + /* the upper layer functions don't want empty quota records...*/ + return -1; + } + + break; +#endif /* HAVE_GROUP_QUOTA */ + case SMB_USER_FS_QUOTA_TYPE: + id.uid = getuid(); + + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))==0) { + qflags |= QUOTAS_DENY_DISK; + } + + ret = 0; + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + id.gid = getgid(); + + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))==0) { + qflags |= QUOTAS_DENY_DISK; + } + + ret = 0; + break; +#endif /* HAVE_GROUP_QUOTA */ + default: + errno = ENOSYS; + return -1; + } + + dp->bsize = bsize; + dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; + dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; + dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; + dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; + dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; + dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks; + + + dp->qflags = qflags; + + return ret; +} + +/**************************************************************************** + Abstract out the quotactl_4A set calls. +****************************************************************************/ +int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + uint32 qflags = 0; + uint32 oldqflags = 0; + struct dqblk D; + SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + + ZERO_STRUCT(D); + + if (bsize == dp->bsize) { + D.dqb_bsoftlimit = dp->softlimit; + D.dqb_bhardlimit = dp->hardlimit; + D.dqb_ihardlimit = dp->ihardlimit; + D.dqb_isoftlimit = dp->isoftlimit; + } else { + D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize; + D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize; + D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize; + D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize; + } + + qflags = dp->qflags; + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (void *)&D); + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_QUOTA_TYPE: + ret = quotactl(QCMD(Q_SETQLIM,GRPQUOTA), bdev, id.gid, (void *)&D); + break; +#endif /* HAVE_GROUP_QUOTA */ + case SMB_USER_FS_QUOTA_TYPE: + /* this stuff didn't work as it should: + * switching on/off quota via quotactl() + * didn't work! + * So we just return 0 + * --metze + * + * On HPUX we didn't have the mount path, + * we need to fix sys_path_to_bdev() + * + */ +#if 0 + id.uid = getuid(); + + ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D); + + if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) { + if (ret == 0) { + char *quota_file = NULL; + + asprintf("a_file,"/%s/%s%s",path, QUOTAFILENAME,USERQUOTAFILE_EXTENSION); + if (quota_file == NULL) { + DEBUG(0,("asprintf() failed!\n")); + errno = ENOMEM; + return -1; + } + + ret = quotactl(QCMD(Q_QUOTAON,USRQUOTA), bdev, -1,(void *)quota_file); + } else { + ret = 0; + } + } else { + if (ret != 0) { + /* turn off */ + ret = quotactl(QCMD(Q_QUOTAOFF,USRQUOTA), bdev, -1, (void *)0); + } else { + ret = 0; + } + } + + DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", + ret,errno,strerror(errno),id.uid,bdev)); +#else + id.uid = getuid(); + + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + + if (oldqflags == qflags) { + ret = 0; + } else { + ret = -1; + } +#endif + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + /* this stuff didn't work as it should: + * switching on/off quota via quotactl() + * didn't work! + * So we just return 0 + * --metze + * + * On HPUX we didn't have the mount path, + * we need to fix sys_path_to_bdev() + * + */ +#if 0 + id.gid = getgid(); + + ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (void *)&D); + + if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) { + if (ret == 0) { + char *quota_file = NULL; + + asprintf("a_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION); + if (quota_file == NULL) { + DEBUG(0,("asprintf() failed!\n")); + errno = ENOMEM; + return -1; + } + + ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), bdev, -1,(void *)quota_file); + } else { + ret = 0; + } + } else { + if (ret != 0) { + /* turn off */ + ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), bdev, -1, (void *)0); + } else { + ret = 0; + } + } + + DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", + ret,errno,strerror(errno),id.gid,bdev)); +#else + id.gid = getgid(); + + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + + if (oldqflags == qflags) { + ret = 0; + } else { + ret = -1; + } +#endif + break; +#endif /* HAVE_GROUP_QUOTA */ + default: + errno = ENOSYS; + return -1; + } + + return ret; +} + +#else /* HAVE_QUOTACTL_4A */ + void dummy_sysquotas_4A(void){} +#endif /* HAVE_QUOTACTL_4A */ diff --git a/source3/lib/sysquotas_linux.c b/source3/lib/sysquotas_linux.c new file mode 100644 index 0000000000..be42fa23f4 --- /dev/null +++ b/source3/lib/sysquotas_linux.c @@ -0,0 +1,485 @@ +/* + Unix SMB/CIFS implementation. + System QUOTA function wrappers for LINUX + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include "includes.h" + +#ifdef HAVE_QUOTACTL_LINUX + +#include "samba_linux_quota.h" + +/**************************************************************************** + Abstract out the v1 Linux quota get calls. +****************************************************************************/ +static int sys_get_linux_v1_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + uint32 qflags = 0; + struct v1_kern_dqblk D; + SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + + ZERO_STRUCT(D); + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) { + return ret; + } + + break; + case SMB_GROUP_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) { + return ret; + } + + break; + case SMB_USER_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { + qflags |= QUOTAS_DENY_DISK; + } + + break; + case SMB_GROUP_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { + qflags |= QUOTAS_DENY_DISK; + } + + break; + default: + errno = ENOSYS; + return -1; + } + + dp->bsize = bsize; + dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; + dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; + dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; + dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; + dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; + dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks; + + + dp->qflags = qflags; + + return ret; +} + +/**************************************************************************** + Abstract out the v1 Linux quota set calls. +****************************************************************************/ +static int sys_set_linux_v1_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + uint32 qflags = 0; + uint32 oldqflags = 0; + struct v1_kern_dqblk D; + SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + + ZERO_STRUCT(D); + + if (bsize == dp->bsize) { + D.dqb_bsoftlimit = dp->softlimit; + D.dqb_bhardlimit = dp->hardlimit; + D.dqb_ihardlimit = dp->ihardlimit; + D.dqb_isoftlimit = dp->isoftlimit; + } else { + D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize; + D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize; + D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize; + D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize; + } + + qflags = dp->qflags; + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + ret = quotactl(QCMD(Q_V1_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D); + break; + case SMB_GROUP_QUOTA_TYPE: + ret = quotactl(QCMD(Q_V1_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D); + break; + case SMB_USER_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + + break; + case SMB_GROUP_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + + break; + default: + errno = ENOSYS; + return -1; + } + + return ret; +} + +/**************************************************************************** + Abstract out the v2 Linux quota get calls. +****************************************************************************/ +static int sys_get_linux_v2_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + uint32 qflags = 0; + struct v2_kern_dqblk D; + SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + + ZERO_STRUCT(D); + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) { + return ret; + } + + break; + case SMB_GROUP_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) { + return ret; + } + + break; + case SMB_USER_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { + qflags |= QUOTAS_DENY_DISK; + } + + break; + case SMB_GROUP_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { + qflags |= QUOTAS_DENY_DISK; + } + + break; + default: + errno = ENOSYS; + return -1; + } + + dp->bsize = bsize; + dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; + dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; + dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; + dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; + dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; + dp->curblocks = (SMB_BIG_UINT)D.dqb_curspace/bsize; + + + dp->qflags = qflags; + + return ret; +} + +/**************************************************************************** + Abstract out the v2 Linux quota set calls. +****************************************************************************/ +static int sys_set_linux_v2_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + uint32 qflags = 0; + uint32 oldqflags = 0; + struct v2_kern_dqblk D; + SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + + ZERO_STRUCT(D); + + if (bsize == dp->bsize) { + D.dqb_bsoftlimit = dp->softlimit; + D.dqb_bhardlimit = dp->hardlimit; + D.dqb_ihardlimit = dp->ihardlimit; + D.dqb_isoftlimit = dp->isoftlimit; + } else { + D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize; + D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize; + D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize; + D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize; + } + + qflags = dp->qflags; + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + ret = quotactl(QCMD(Q_V2_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D); + break; + case SMB_GROUP_QUOTA_TYPE: + ret = quotactl(QCMD(Q_V2_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D); + break; + case SMB_USER_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + + break; + case SMB_GROUP_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + + break; + default: + errno = ENOSYS; + return -1; + } + + return ret; +} + +/**************************************************************************** + Abstract out the generic Linux quota get calls. +****************************************************************************/ +static int sys_get_linux_gen_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + uint32 qflags = 0; + struct if_dqblk D; + SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + + ZERO_STRUCT(D); + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) { + return ret; + } + + break; + case SMB_GROUP_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) { + return ret; + } + + break; + case SMB_USER_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { + qflags |= QUOTAS_DENY_DISK; + } + + break; + case SMB_GROUP_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { + qflags |= QUOTAS_DENY_DISK; + } + + break; + default: + errno = ENOSYS; + return -1; + } + + dp->bsize = bsize; + dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; + dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; + dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; + dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; + dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; + dp->curblocks = (SMB_BIG_UINT)D.dqb_curspace/bsize; + + + dp->qflags = qflags; + + return ret; +} + +/**************************************************************************** + Abstract out the gen Linux quota set calls. +****************************************************************************/ +static int sys_set_linux_gen_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + uint32 qflags = 0; + uint32 oldqflags = 0; + struct if_dqblk D; + SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + + ZERO_STRUCT(D); + + if (bsize == dp->bsize) { + D.dqb_bsoftlimit = dp->softlimit; + D.dqb_bhardlimit = dp->hardlimit; + D.dqb_ihardlimit = dp->ihardlimit; + D.dqb_isoftlimit = dp->isoftlimit; + } else { + D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize; + D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize; + D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize; + D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize; + } + + qflags = dp->qflags; + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + ret = quotactl(QCMD(Q_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D); + break; + case SMB_GROUP_QUOTA_TYPE: + ret = quotactl(QCMD(Q_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D); + break; + case SMB_USER_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + + break; + case SMB_GROUP_FS_QUOTA_TYPE: + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + + break; + default: + errno = ENOSYS; + return -1; + } + + return ret; +} + +/**************************************************************************** + Abstract out the Linux quota get calls. +****************************************************************************/ +int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + + if (!path||!bdev||!dp) + smb_panic("sys_set_vfs_quota: called with NULL pointer"); + + ZERO_STRUCT(*dp); + dp->qtype = qtype; + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + case SMB_GROUP_QUOTA_TYPE: + if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { + if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { + if ((ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { + return ret; + } + } + } + + if ((dp->curblocks==0)&& + (dp->softlimit==0)&& + (dp->hardlimit==0)) { + /* the upper layer functions don't want empty quota records...*/ + return -1; + } + + break; + case SMB_USER_FS_QUOTA_TYPE: + id.uid = getuid(); + + if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { + if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { + ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp); + } + } + + ret = 0; + break; + case SMB_GROUP_FS_QUOTA_TYPE: + id.gid = getgid(); + + if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { + if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { + ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp); + } + } + + ret = 0; + break; + default: + errno = ENOSYS; + return -1; + } + + return ret; +} + +/**************************************************************************** + Abstract out the Linux quota set calls. +****************************************************************************/ +int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + uint32 oldqflags = 0; + + if (!path||!bdev||!dp) + smb_panic("sys_set_vfs_quota: called with NULL pointer"); + + oldqflags = dp->qflags; + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + case SMB_GROUP_QUOTA_TYPE: + if ((ret=sys_set_linux_gen_quota(path, bdev, qtype, id, dp))) { + if ((ret=sys_set_linux_v2_quota(path, bdev, qtype, id, dp))) { + if ((ret=sys_set_linux_v1_quota(path, bdev, qtype, id, dp))) { + return ret; + } + } + } + break; + case SMB_USER_FS_QUOTA_TYPE: + id.uid = getuid(); + + if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))) { + if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))) { + ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp); + } + } + + if (oldqflags == dp->qflags) { + ret = 0; + } else { + ret = -1; + } + break; + case SMB_GROUP_FS_QUOTA_TYPE: + id.gid = getgid(); + + if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))) { + if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))) { + ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp); + } + } + + if (oldqflags == dp->qflags) { + ret = 0; + } else { + ret = -1; + } + + break; + default: + errno = ENOSYS; + return -1; + } + + return ret; +} + +#else /* HAVE_QUOTACTL_LINUX */ + void dummy_sysquotas_linux(void){} +#endif /* HAVE_QUOTACTL_LINUX */ diff --git a/source3/lib/sysquotas_xfs.c b/source3/lib/sysquotas_xfs.c new file mode 100644 index 0000000000..6d7d9f9e6a --- /dev/null +++ b/source3/lib/sysquotas_xfs.c @@ -0,0 +1,306 @@ +/* + Unix SMB/CIFS implementation. + System QUOTA function wrappers for XFS + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include "includes.h" + +#ifndef HAVE_SYS_QUOTAS +#ifdef HAVE_XFS_QUOTAS +#undef HAVE_XFS_QUOTAS +#endif +#endif + +#ifdef HAVE_XFS_QUOTAS + +#ifdef HAVE_LINUX_XFS_QUOTAS +#include "samba_linux_quota.h" +#include "samba_xfs_quota.h" +#define HAVE_GROUP_QUOTA +#else /* IRIX */ +#include +#endif + +/* on IRIX */ +#ifndef Q_XQUOTAON +#define Q_XQUOTAON Q_QUOTAON +#endif /* Q_XQUOTAON */ +#ifndef Q_XQUOTAOFF +#define Q_XQUOTAOFF Q_QUOTAOFF +#endif /* Q_XQUOTAOFF */ +#ifndef Q_XGETQSTAT +#define Q_XGETQSTAT Q_GETQSTAT +#endif /* Q_XGETQSTAT */ + +/* currently doesn't support Group and Project quotas on IRIX + */ + +#ifndef QCMD +#define QCMD(x,y) x +#endif + +/* + * IRIX has BBSIZE in + */ +#ifndef BBSHIFT +#define BBSHIFT 9 +#endif /* BBSHIFT */ +#ifndef BBSIZE +#define BBSIZE (1<qtype = qtype; + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + if ((ret=quotactl(QCMD(Q_XGETQUOTA,XFS_USER_QUOTA), bdev, id.uid, (caddr_t)&D))) + return ret; + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_QUOTA_TYPE: + if ((ret=quotactl(QCMD(Q_XGETQUOTA,XFS_GROUP_QUOTA), bdev, id.gid, (caddr_t)&D))) + return ret; + break; +#endif /* HAVE_GROUP_QUOTA */ + case SMB_USER_FS_QUOTA_TYPE: + quotactl(QCMD(Q_XGETQSTAT,XFS_USER_QUOTA), bdev, -1, (caddr_t)&F); + + if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) { + qflags |= QUOTAS_DENY_DISK; + } + else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) { + qflags |= QUOTAS_ENABLED; + } + + ret = 0; + + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + quotactl(QCMD(Q_XGETQSTAT,XFS_GROUP_QUOTA), bdev, -1, (caddr_t)&F); + + if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) { + qflags |= QUOTAS_DENY_DISK; + } + else if (F.qs_flags & XFS_QUOTA_GDQ_ACCT) { + qflags |= QUOTAS_ENABLED; + } + + ret = 0; + + break; +#endif /* HAVE_GROUP_QUOTA */ + default: + errno = ENOSYS; + return -1; + } + + dp->bsize = bsize; + dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit; + dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit; + dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit; + dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit; + dp->curinodes = (SMB_BIG_UINT)D.d_icount; + dp->curblocks = (SMB_BIG_UINT)D.d_bcount; + dp->qflags = qflags; + + return ret; +} + +/**************************************************************************** + Abstract out the XFS Quota Manager quota set call. +****************************************************************************/ +int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) +{ + int ret = -1; + uint32 qflags = 0; + SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE; + struct fs_disk_quota D; + struct fs_quota_stat F; + int q_on = 0; + int q_off = 0; + ZERO_STRUCT(D); + ZERO_STRUCT(F); + + if (!bdev||!dp) + smb_panic("sys_set_xfs_quota: called with NULL pointer"); + + if (bsize == dp->bsize) { + D.d_blk_softlimit = dp->softlimit; + D.d_blk_hardlimit = dp->hardlimit; + D.d_ino_hardlimit = dp->ihardlimit; + D.d_ino_softlimit = dp->isoftlimit; + } else { + D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize; + D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize; + D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize; + D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize; + } + + qflags = dp->qflags; + + switch (qtype) { + case SMB_USER_QUOTA_TYPE: + D.d_fieldmask |= FS_DQ_LIMIT_MASK; + ret = quotactl(QCMD(Q_XSETQLIM,XFS_USER_QUOTA), bdev, id.uid, (caddr_t)&D); + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_QUOTA_TYPE: + D.d_fieldmask |= FS_DQ_LIMIT_MASK; + ret = quotactl(QCMD(Q_XSETQLIM,XFS_GROUP_QUOTA), bdev, id.gid, (caddr_t)&D); + break; +#endif /* HAVE_GROUP_QUOTA */ + case SMB_USER_FS_QUOTA_TYPE: + quotactl(QCMD(Q_XGETQSTAT,XFS_USER_QUOTA), bdev, -1, (caddr_t)&F); + + if (qflags & QUOTAS_DENY_DISK) { + if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD)) + q_on |= XFS_QUOTA_UDQ_ENFD; + if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) + q_on |= XFS_QUOTA_UDQ_ACCT; + + if (q_on != 0) { + ret = quotactl(QCMD(Q_XQUOTAON,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_on); + } else { + ret = 0; + } + + } else if (qflags & QUOTAS_ENABLED) { + if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) + q_off |= XFS_QUOTA_UDQ_ENFD; + + if (q_off != 0) { + ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_off); + } else { + ret = 0; + } + + if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) + q_on |= XFS_QUOTA_UDQ_ACCT; + + if (q_on != 0) { + ret = quotactl(QCMD(Q_XQUOTAON,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_on); + } else { + ret = 0; + } + } else { +#if 0 + /* Switch on XFS_QUOTA_UDQ_ACCT didn't work! + * only swittching off XFS_QUOTA_UDQ_ACCT work + */ + if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) + q_off |= XFS_QUOTA_UDQ_ENFD; + if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) + q_off |= XFS_QUOTA_UDQ_ACCT; + + if (q_off !=0) { + ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_off); + } else { + ret = 0; + } +#else + ret = -1; +#endif + } + + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + quotactl(QCMD(Q_XGETQSTAT,XFS_GROUP_QUOTA), bdev, -1, (caddr_t)&F); + + if (qflags & QUOTAS_DENY_DISK) { + if (!(F.qs_flags & XFS_QUOTA_GDQ_ENFD)) + q_on |= XFS_QUOTA_GDQ_ENFD; + if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT)) + q_on |= XFS_QUOTA_GDQ_ACCT; + + if (q_on != 0) { + ret = quotactl(QCMD(Q_XQUOTAON,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_on); + } else { + ret = 0; + } + + } else if (qflags & QUOTAS_ENABLED) { + if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) + q_off |= XFS_QUOTA_GDQ_ENFD; + + if (q_off != 0) { + ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_off); + } else { + ret = 0; + } + + if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT)) + q_on |= XFS_QUOTA_GDQ_ACCT; + + if (q_on != 0) { + ret = quotactl(QCMD(Q_XQUOTAON,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_on); + } else { + ret = 0; + } + } else { +#if 0 + /* Switch on XFS_QUOTA_UDQ_ACCT didn't work! + * only swittching off XFS_QUOTA_UDQ_ACCT work + */ + if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) + q_off |= XFS_QUOTA_GDQ_ENFD; + if (F.qs_flags & XFS_QUOTA_GDQ_ACCT) + q_off |= XFS_QUOTA_GDQ_ACCT; + + if (q_off !=0) { + ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_off); + } else { + ret = 0; + } +#else + ret = -1; +#endif + } + + break; +#endif /* HAVE_GROUP_QUOTA */ + default: + errno = ENOSYS; + return -1; + } + + return ret; +} + +#else /* HAVE_XFS_QUOTAS */ + void dummy_sysquotas_xfs(void){} +#endif /* HAVE_XFS_QUOTAS */ diff --git a/source3/lib/talloctort.c b/source3/lib/talloctort.c index ad5de38581..0cdf693bb9 100644 --- a/source3/lib/talloctort.c +++ b/source3/lib/talloctort.c @@ -51,9 +51,9 @@ int main(void) } for (i = 0; i < NCTX; i++) { - printf("talloc@%p %-40s %dkB\n", ctx[i], + printf("talloc@%p %-40s %ldkB\n", ctx[i], talloc_pool_name(ctx[i]), - talloc_pool_size(ctx[i]) >> 10); + (unsigned long)talloc_pool_size(ctx[i]) >> 10); } printf("%s", talloc_describe_all(ctx[0])); diff --git a/source3/lib/time.c b/source3/lib/time.c index 635ede9be2..faca2cba87 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -465,10 +465,9 @@ void unix_to_nt_time_abs(NTTIME *nt, time_t t) nt->low=~nt->low; } - /**************************************************************************** -take an NTTIME structure, containing high / low time. convert to unix time. -lkclXXXX this may need 2 SIVALs not a memcpy. we'll see... +take a Unix time and convert to an NTTIME structure and place in buffer +pointed to by p. ****************************************************************************/ void put_long_date(char *p,time_t t) { diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index f552b38e67..d93f39696f 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -697,7 +697,7 @@ char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n) if (!dest) { DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line)); - return NULL; + return(NULL); } if (!src) { @@ -1196,7 +1196,7 @@ char *strchr_m(const char *src, char c) for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) { if (*s == c) - return s; + return (char *)s; } if (!*s) @@ -1244,7 +1244,7 @@ char *strrchr_m(const char *s, char c) break; } /* No - we have a match ! */ - return cp; + return (char *)cp; } } while (cp-- != s); if (!got_mb) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 5122803597..1ab71c6ee5 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -124,13 +124,13 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip { DATA_BLOB blob; struct berval cred, *scred; - unsigned char sk[16]; + DATA_BLOB session_key; int rc; - blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, sk); + rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key); - if (!blob.data) { - return ADS_ERROR(LDAP_OPERATIONS_ERROR); + if (rc) { + return ADS_ERROR_KRB5(rc); } /* now send the auth packet and we should be done */ @@ -140,6 +140,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred); data_blob_free(&blob); + data_blob_free(&session_key); return ADS_ERROR(rc); } @@ -166,6 +167,8 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) blob = data_blob(scred->bv_val, scred->bv_len); + ber_bvfree(scred); + #if 0 file_save("sasl_spnego.dat", blob.data, blob.length); #endif @@ -196,9 +199,13 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) status = ads_sasl_spnego_krb5_bind(ads, principal); if (ADS_ERR_OK(status)) return status; - if (ads_kinit_password(ads) == 0) { + + status = ADS_ERROR_KRB5(ads_kinit_password(ads)); + + if (ADS_ERR_OK(status)) { status = ads_sasl_spnego_krb5_bind(ads, principal); } + /* only fallback to NTLMSSP if allowed */ if (ADS_ERR_OK(status) || !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 28de7fc9f3..707a33881d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -53,6 +53,13 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, if (passlen > sizeof(pword)-1) return False; + /* LANMAN servers predate NT status codes and Unicode and ignore those + smb flags so we must disable the corresponding default capabilities + that would otherwise cause the Unicode and NT Status flags to be + set (and even returned by the server) */ + + cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32); + /* if in share level security then don't send a password now */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) passlen = 0; @@ -493,19 +500,22 @@ static void use_in_memory_ccache(void) { Do a spnego/kerberos encrypted session setup. ****************************************************************************/ -static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) +static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) { DATA_BLOB blob2, negTokenTarg; DATA_BLOB session_key_krb5; DATA_BLOB null_blob = data_blob(NULL, 0); - + int rc; + DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(principal, 0, &session_key_krb5); + rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5); - if (!negTokenTarg.data) - return NT_STATUS_UNSUCCESSFUL; + if (rc) { + DEBUG(1, ("spnego_gen_negTokenTarg failed: %s\n", error_message(rc))); + return ADS_ERROR_KRB5(rc); + } #if 0 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); @@ -524,10 +534,10 @@ static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *pr if (cli_is_error(cli)) { if (NT_STATUS_IS_OK(cli_nt_error(cli))) { - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); } } - return NT_STATUS_OK; + return ADS_ERROR_NT(cli_nt_error(cli)); } #endif /* HAVE_KRB5 */ @@ -537,7 +547,7 @@ static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *pr ****************************************************************************/ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, - const char *pass, const char *workgroup) + const char *pass, const char *domain) { struct ntlmssp_state *ntlmssp_state; NTSTATUS nt_status; @@ -556,7 +566,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { return nt_status; } - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, workgroup))) { + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) { @@ -654,8 +664,8 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use Do a spnego encrypted session setup. ****************************************************************************/ -NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, - const char *pass, const char *workgroup) +ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, + const char *pass, const char *domain) { char *principal; char *OIDs[ASN1_MAX_OIDS]; @@ -682,7 +692,7 @@ NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, reply */ if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { data_blob_free(&blob); - return NT_STATUS_INVALID_PARAMETER; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } data_blob_free(&blob); @@ -712,11 +722,11 @@ NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, if (ret){ DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; + return ADS_ERROR_KRB5(ret); } } - return cli_session_setup_kerberos(cli, principal, workgroup); + return cli_session_setup_kerberos(cli, principal, domain); } #endif @@ -724,7 +734,7 @@ NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, ntlmssp: - return cli_session_setup_ntlmssp(cli, user, pass, workgroup); + return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, domain)); } /**************************************************************************** @@ -805,9 +815,9 @@ BOOL cli_session_setup(struct cli_state *cli, /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) { - NTSTATUS nt_status; - if (!NT_STATUS_IS_OK(nt_status = cli_session_setup_spnego(cli, user, pass, workgroup))) { - DEBUG(3, ("SPENGO login failed: %s\n", get_friendly_nt_error_msg(nt_status))); + ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup); + if (!ADS_ERR_OK(status)) { + DEBUG(3, ("SPENGO login failed: %s\n", ads_errstr(status))); return False; } return True; diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5568b5e033..15b244a83d 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -307,14 +307,14 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *session_key_krb5) +int cli_krb5_get_ticket(const char *principal, time_t time_offset, + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) { krb5_error_code retval; krb5_data packet; krb5_ccache ccdef; krb5_context context; krb5_auth_context auth_context = NULL; - DATA_BLOB ret; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC, @@ -356,17 +356,18 @@ DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BL get_krb5_smb_session_key(context, auth_context, session_key_krb5, False); - ret = data_blob(packet.data, packet.length); + *ticket = data_blob(packet.data, packet.length); + /* Hmm, heimdal dooesn't have this - what's the correct call? */ -/* krb5_free_data_contents(context, &packet); */ - krb5_free_context(context); - return ret; +#ifdef HAVE_KRB5_FREE_DATA_CONTENTS + krb5_free_data_contents(context, &packet); +#endif failed: if ( context ) krb5_free_context(context); - return data_blob(NULL, 0); + return retval; } BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote) @@ -410,10 +411,11 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *session_key_krb5) - { +int cli_krb5_get_ticket(const char *principal, time_t time_offset, + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) +{ DEBUG(0,("NO KERBEROS SUPPORT\n")); - return data_blob(NULL, 0); - } + return 1; +} #endif diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 92543736ff..e6cadc466c 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -323,27 +323,30 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *session_key_krb5) +int spnego_gen_negTokenTarg(const char *principal, int time_offset, + DATA_BLOB *targ, + DATA_BLOB *session_key_krb5) { - DATA_BLOB tkt, tkt_wrapped, targ; + int retval; + DATA_BLOB tkt, tkt_wrapped; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service and extract the session key */ - tkt = cli_krb5_get_ticket(principal, time_offset, session_key_krb5); + retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5); - if (tkt.data == NULL) - return tkt; + if (retval) + return retval; /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ - targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); + *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); data_blob_free(&tkt_wrapped); data_blob_free(&tkt); - return targ; + return retval; } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c7cc4848b7..83902971b0 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -884,6 +884,40 @@ static BOOL resolve_hosts(const char *name, int name_type, */ struct hostent *hp; + if ( name_type != 0x20 && name_type != 0x0) { + DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type)); + return False; + } + + *return_iplist = NULL; + *return_count = 0; + + DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type)); + + if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { + struct in_addr return_ip; + putip((char *)&return_ip,(char *)hp->h_addr); + *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service)); + if(*return_iplist == NULL) { + DEBUG(3,("resolve_hosts: malloc fail !\n")); + return False; + } + (*return_iplist)->ip = return_ip; + (*return_iplist)->port = PORT_NONE; + *return_count = 1; + return True; + } + return False; +} + +/******************************************************** + Resolve via "ADS" method. +*********************************************************/ + +static BOOL resolve_ads(const char *name, int name_type, + struct ip_service **return_iplist, int *return_count) +{ + #ifdef HAVE_ADS if ( name_type == 0x1c ) { int count, i = 0; @@ -935,28 +969,11 @@ static BOOL resolve_hosts(const char *name, int name_type, *return_count = i; return True; - } + } else #endif /* HAVE_ADS */ - - *return_iplist = NULL; - *return_count = 0; - - DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name)); - - if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { - struct in_addr return_ip; - putip((char *)&return_ip,(char *)hp->h_addr); - *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service)); - if(*return_iplist == NULL) { - DEBUG(3,("resolve_hosts: malloc fail !\n")); - return False; - } - (*return_iplist)->ip = return_ip; - (*return_iplist)->port = PORT_NONE; - *return_count = 1; - return True; + { + return False; } - return False; } /******************************************************************* @@ -1034,14 +1051,17 @@ static BOOL internal_resolve_name(const char *name, int name_type, while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { - /* deal with 0x20 & 0x1c names here. The latter will result - in a SRV record lookup for _ldap._tcp. if we are using - 'security = ads' */ - if ( name_type==0x20 || name_type == 0x1c ) { - if (resolve_hosts(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } + if (resolve_hosts(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else if(strequal( tok, "ads")) { + /* deal with 0x1c names here. This will result in a + SRV record lookup for _ldap._tcp. if we + are using 'security = ads' */ + if (resolve_ads(name, name_type, return_iplist, return_count)) { + result = True; + goto done; } } else if(strequal( tok, "lmhosts")) { if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { @@ -1207,14 +1227,14 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) /********************************************************************* small wrapper function to get the DC list and sort it if neccessary *********************************************************************/ -BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL dns_only ) +BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ) { BOOL ordered; DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", - (dns_only ? "hosts" : lp_name_resolve_order()))); + (ads_only ? "ads" : lp_name_resolve_order()))); - if ( !get_dc_list(domain, ip_list, count, dns_only, &ordered) ) + if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) return False; /* only sort if we don't already have an ordered list */ @@ -1230,11 +1250,11 @@ BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *c *********************************************************/ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, - int *count, BOOL dns_only, int *ordered) + int *count, BOOL ads_only, int *ordered) { /* defined the name resolve order to internal_name_resolve() only used for looking up 0x1c names */ - const char *resolve_oder = (dns_only ? "hosts" : lp_name_resolve_order()); + const char *resolve_oder = (ads_only ? "ads" : lp_name_resolve_order()); *ordered = False; diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d645a2fffb..c3abd63818 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -361,7 +361,7 @@ void unlock_share_entry(connection_struct *conn, } /******************************************************************* - Lock a hash bucket entry. Use an fsp for convenience. + Lock a hash bucket entry. use a fsp for convenience ******************************************************************/ BOOL lock_share_entry_fsp(files_struct *fsp) @@ -370,7 +370,7 @@ BOOL lock_share_entry_fsp(files_struct *fsp) } /******************************************************************* - Unlock a hash bucket entry. Use an fsp for convenience. + Unlock a hash bucket entry. ******************************************************************/ void unlock_share_entry_fsp(files_struct *fsp) diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index fc66e0d6b4..728796ea21 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -255,7 +255,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", q = ALIGN4(q, buf); } - DEBUG(3,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %d\n", len, PTR_DIFF(q, buf) )); + DEBUG(3,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %ld\n", len, (unsigned long)PTR_DIFF(q, buf) )); if (len - PTR_DIFF(q, buf) > 8) { /* with NT5 clients we can sometimes diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 7d25524f8e..c7dc89d43f 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -298,18 +298,20 @@ static BOOL wbinfo_domain_info(const char *domain_name) /* Display response */ - d_printf("Name : %s\n", response.data.domain_info.name); - d_printf("Alt_Name: %s\n", response.data.domain_info.alt_name); + d_printf("Name : %s\n", response.data.domain_info.name); + d_printf("Alt_Name : %s\n", response.data.domain_info.alt_name); - d_printf("SID : %s\n", response.data.domain_info.sid); + d_printf("SID : %s\n", response.data.domain_info.sid); - d_printf("Native : %s\n", + d_printf("Active Directory : %s\n", + response.data.domain_info.active_directory ? "Yes" : "No"); + d_printf("Native : %s\n", response.data.domain_info.native_mode ? "Yes" : "No"); - d_printf("Primary : %s\n", + d_printf("Primary : %s\n", response.data.domain_info.primary ? "Yes" : "No"); - d_printf("Sequence: %d\n", response.data.domain_info.sequence_number); + d_printf("Sequence : %d\n", response.data.domain_info.sequence_number); return True; } @@ -909,14 +911,14 @@ static void wbinfo_get_auth_user(void) char *user, *domain, *password; /* Lift data from secrets file */ + + secrets_fetch_ipc_userpass(&user, &domain, &password); - secrets_init(); - - user = secrets_fetch(SECRETS_AUTH_USER, NULL); - domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL); - password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL); + if ((!user || !*user) && (!domain || !*domain ) && (!password || !*password)){ - if (!user && !domain && !password) { + SAFE_FREE(user); + SAFE_FREE(domain); + SAFE_FREE(password); d_printf("No authorised user configured\n"); return; } diff --git a/source3/nsswitch/winbind_nss_freebsd.c b/source3/nsswitch/winbind_nss_freebsd.c new file mode 100644 index 0000000000..b73a4ce44f --- /dev/null +++ b/source3/nsswitch/winbind_nss_freebsd.c @@ -0,0 +1,81 @@ +/* + Unix SMB/CIFS implementation. + + AIX loadable authentication module, providing identification + routines against Samba winbind/Windows NT Domain + + Copyright (C) Aaron Collins 2003 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "winbind_client.h" + +/* Make sure that the module gets registered needed by freebsd 5.1 */ + +extern enum nss_status _nss_winbind_getgrent_r(struct group *, char *, size_t, + int *); +extern enum nss_status _nss_winbind_getgrnam_r(const char *, struct group *, + char *, size_t, int *); +extern enum nss_status _nss_winbind_getgrgid_r(gid_t gid, struct group *, char *, + size_t, int *); +extern enum nss_status _nss_winbind_setgrent(void); +extern enum nss_status _nss_winbind_endgrent(void); + +extern enum nss_status _nss_winbind_getpwent_r(struct passwd *, char *, size_t, + int *); +extern enum nss_status _nss_winbind_getpwnam_r(const char *, struct passwd *, + char *, size_t, int *); +extern enum nss_status _nss_winbind_getpwuid_r(gid_t gid, struct passwd *, char *, + size_t, int *); +extern enum nss_status _nss_winbind_setpwent(void); +extern enum nss_status _nss_winbind_endpwent(void); + +NSS_METHOD_PROTOTYPE(__nss_compat_getgrnam_r); +NSS_METHOD_PROTOTYPE(__nss_compat_getgrgid_r); +NSS_METHOD_PROTOTYPE(__nss_compat_getgrent_r); +NSS_METHOD_PROTOTYPE(__nss_compat_setgrent); +NSS_METHOD_PROTOTYPE(__nss_compat_endgrent); + +NSS_METHOD_PROTOTYPE(__nss_compat_getpwnam_r); +NSS_METHOD_PROTOTYPE(__nss_compat_getpwuid_r); +NSS_METHOD_PROTOTYPE(__nss_compat_getpwent_r); +NSS_METHOD_PROTOTYPE(__nss_compat_setpwent); +NSS_METHOD_PROTOTYPE(__nss_compat_endpwent); + +static ns_mtab methods[] = { +{ NSDB_GROUP, "getgrnam_r", __nss_compat_getgrnam_r, _nss_winbind_getgrnam_r }, +{ NSDB_GROUP, "getgrgid_r", __nss_compat_getgrgid_r, _nss_winbind_getgrgid_r }, +{ NSDB_GROUP, "getgrent_r", __nss_compat_getgrent_r, _nss_winbind_getgrent_r }, +{ NSDB_GROUP, "endgrent", __nss_compat_setgrent, _nss_winbind_setgrent }, +{ NSDB_GROUP, "setgrent", __nss_compat_endgrent, _nss_winbind_endgrent }, + +{ NSDB_PASSWD, "getpwnam_r", __nss_compat_getpwnam_r, _nss_winbind_getpwnam_r }, +{ NSDB_PASSWD, "getpwuid_r", __nss_compat_getpwuid_r, _nss_winbind_getpwuid_r }, +{ NSDB_PASSWD, "getpwent_r", __nss_compat_getpwent_r, _nss_winbind_getpwent_r }, +{ NSDB_PASSWD, "endpwent", __nss_compat_setpwent, _nss_winbind_setpwent }, +{ NSDB_PASSWD, "setpwent", __nss_compat_endpwent, _nss_winbind_endpwent }, + +}; + +ns_mtab * +nss_module_register(const char *source, unsigned int *mtabsize, + nss_module_unregister_fn *unreg) +{ + *mtabsize = sizeof(methods)/sizeof(methods[0]); + *unreg = NULL; + return (methods); +} diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 4c03522461..3124ef6378 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -935,6 +935,8 @@ int main(int argc, char **argv) netsamlogon_cache_init(); /* Non-critical */ + init_domain_list(); + /* Loop waiting for requests */ process_loop(); diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 5dbe422bc1..7c8e6256e1 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -95,7 +95,8 @@ struct winbindd_domain { fstring alt_name; /* alt Domain name (if any) */ DOM_SID sid; /* SID for this domain */ BOOL native_mode; /* is this a win2k domain in native mode ? */ - BOOL primary; /* is this our primary domain ? */ + BOOL active_directory; /* is this a win2k active directory ? */ + BOOL primary; /* is this our primary domain ? */ /* Lookup methods for this domain (LDAP or RPC) */ struct winbindd_methods *methods; diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index ec93d494d0..e6b857f406 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -112,7 +112,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, goto done; } - rc = ads_search_retry(ads, &res, "(objectCategory=user)", attrs); + rc = ads_search_retry(ads, &res, "(objectClass=user)", attrs); if (!ADS_ERR_OK(rc) || !res) { DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc))); goto done; diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index a3c1706b75..8dec89a6aa 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -107,12 +107,14 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain) case SEC_ADS: { extern struct winbindd_methods ads_methods; /* always obey the lp_security parameter for our domain */ - if ( strequal(lp_realm(), domain->alt_name) || strequal(lp_workgroup(), domain->name) ) { + if (domain->primary) { domain->backend = &ads_methods; break; } - if ( domain->native_mode ) { + /* if it have either of the indications of ADS, + use ads_methods */ + if ( domain->active_directory || domain->native_mode ) { domain->backend = &ads_methods; break; } diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 2b561be31d..44fc06fe54 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -174,16 +174,19 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i if ((lp_security() == SEC_ADS) && (new_conn->cli->protocol >= PROTOCOL_NT1 && new_conn->cli->capabilities & CAP_EXTENDED_SECURITY)) { + ADS_STATUS ads_status; new_conn->cli->use_kerberos = True; DEBUG(5, ("connecting to %s from %s with kerberos principal [%s]\n", new_conn->controller, global_myname(), machine_krb5_principal)); - result = NT_STATUS_OK; - - if (!NT_STATUS_IS_OK(result = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal, - machine_password, - lp_workgroup()))) { - DEBUG(4,("failed kerberos session setup with %s\n", nt_errstr(result))); + ads_status = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal, + machine_password, + lp_workgroup()); + if (!ADS_ERR_OK(ads_status)) { + DEBUG(4,("failed kerberos session setup with %s\n", ads_errstr(ads_status))); + result = ads_ntstatus(ads_status); + } else { + result = NT_STATUS_OK; } } new_conn->cli->use_kerberos = False; @@ -405,46 +408,116 @@ static NTSTATUS get_connection_from_cache(struct winbindd_domain *domain, const } /********************************************************************************** + We can 'sense' certain things about the DC by it's replies to certain questions. + + This tells us if this particular remote server is Active Directory, and if it is + native mode. **********************************************************************************/ -BOOL cm_check_for_native_mode_win2k( struct winbindd_domain *domain ) +void set_dc_type_and_flags( struct winbindd_domain *domain ) { NTSTATUS result; struct winbindd_cm_conn conn; DS_DOMINFO_CTR ctr; - BOOL ret = False; + TALLOC_CTX *mem_ctx = NULL; ZERO_STRUCT( conn ); ZERO_STRUCT( ctr ); + domain->native_mode = False; + domain->active_directory = False; if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) { - DEBUG(5, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n", + DEBUG(5, ("set_dc_type_and_flags: Could not open a connection to %s for PIPE_LSARPC (%s)\n", domain->name, nt_errstr(result))); - return False; + return; } if ( conn.cli ) { if ( !NT_STATUS_IS_OK(cli_ds_getprimarydominfo( conn.cli, conn.cli->mem_ctx, DsRolePrimaryDomainInfoBasic, &ctr)) ) { - ret = False; goto done; } } if ( (ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) && !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) ) - ret = True; + domain->native_mode = True; -done: + /* Cheat - shut down the DS pipe, and open LSA */ + + cli_nt_session_close(conn.cli); + + if ( cli_nt_session_open (conn.cli, PI_LSARPC) ) { + char *domain_name = NULL; + char *dns_name = NULL; + DOM_SID *dom_sid = NULL; + + mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n", domain->name); + if (!mem_ctx) { + DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n")); + return; + } + + result = cli_lsa_open_policy2(conn.cli, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &conn.pol); + + if (NT_STATUS_IS_OK(result)) { + /* This particular query is exactly what Win2k clients use + to determine that the DC is active directory */ + result = cli_lsa_query_info_policy2(conn.cli, mem_ctx, + &conn.pol, + 12, &domain_name, + &dns_name, NULL, + NULL, &dom_sid); + } + + if (NT_STATUS_IS_OK(result)) { + if (domain_name) + fstrcpy(domain->name, domain_name); + + if (dns_name) + fstrcpy(domain->alt_name, dns_name); + if (dom_sid) + sid_copy(&domain->sid, dom_sid); + + domain->active_directory = True; + } else { + + result = cli_lsa_open_policy(conn.cli, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &conn.pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = cli_lsa_query_info_policy(conn.cli, mem_ctx, + &conn.pol, 5, &domain_name, + &dom_sid); + + if (NT_STATUS_IS_OK(result)) { + if (domain_name) + fstrcpy(domain->name, domain_name); + + if (dom_sid) + sid_copy(&domain->sid, dom_sid); + } + } + } + +done: + /* close the connection; no other cals use this pipe and it is called only on reestablishing the domain list --jerry */ - + if ( conn.cli ) cli_shutdown( conn.cli ); - return ret; + talloc_destroy(mem_ctx); + + return; } diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 180a3db8e2..b31dc92b38 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -106,7 +106,7 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain, *num_gr_mem = 0; if ( !((group_name_type==SID_NAME_DOM_GRP) || - ((group_name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) ) + ((group_name_type==SID_NAME_ALIAS) && domain->primary)) ) { DEBUG(1, ("SID %s in domain %s isn't a domain group (%d)\n", sid_to_string(sid_string, group_sid), domain->name, @@ -152,15 +152,10 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain, occur in Universal groups on a Windows 2000 native mode server. */ - if (name_types[i] != SID_NAME_USER) { - DEBUG(3, ("name %s isn't a domain user\n", the_name)); - continue; - } + /* make sure to allow machine accounts */ - /* Don't bother with machine accounts */ - - if (the_name[strlen(the_name) - 1] == '$') { - DEBUG(10, ("%s is machine account\n", the_name)); + if (name_types[i] != SID_NAME_USER && name_types[i] != SID_NAME_COMPUTER) { + DEBUG(3, ("name %s isn't a domain user\n", the_name)); continue; } @@ -265,22 +260,20 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) return WINBINDD_OK; } - /* should we deal with users for our domain? */ - - if ( lp_winbind_trusted_domains_only() && strequal(name_domain, lp_workgroup())) { - DEBUG(7,("winbindd_getgrnam: My domain -- rejecting getgrnam() for %s\\%s.\n", - name_domain, name_group)); - return WINBINDD_ERROR; - } - - /* Get info for the domain */ if ((domain = find_domain_from_name(name_domain)) == NULL) { - DEBUG(0, ("could not get domain sid for domain %s\n", + DEBUG(3, ("could not get domain sid for domain %s\n", name_domain)); return WINBINDD_ERROR; } + /* should we deal with users for our domain? */ + + if ( lp_winbind_trusted_domains_only() && domain->primary) { + DEBUG(7,("winbindd_getgrnam: My domain -- rejecting getgrnam() for %s\\%s.\n", + name_domain, name_group)); + return WINBINDD_ERROR; + } /* Get rid and name type from name */ @@ -292,7 +285,7 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) } if ( !((name_type==SID_NAME_DOM_GRP) || - ((name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) ) + ((name_type==SID_NAME_ALIAS) && domain->primary)) ) { DEBUG(1, ("name '%s' is not a local or domain group: %d\n", name_group, name_type)); @@ -383,7 +376,7 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) } if ( !((name_type==SID_NAME_DOM_GRP) || - ((name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) ) + ((name_type==SID_NAME_ALIAS) && domain->primary) )) { DEBUG(1, ("name '%s' is not a local or domain group: %d\n", group_name, name_type)); @@ -441,7 +434,7 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) are a member of a Samba domain */ if ( (IS_DC || lp_winbind_trusted_domains_only()) - && strequal(domain->name, lp_workgroup()) ) + && domain->primary ) { continue; } @@ -547,7 +540,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent) and are not using LDAP to get the groups */ if ( lp_security() != SEC_ADS && domain->native_mode - && strequal(lp_workgroup(), domain->name) ) + && domain->primary ) { DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n")); @@ -887,7 +880,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) extra_data[extra_data_len++] = ','; } - free(groups.sam_entries); + SAFE_FREE(groups.sam_entries); } /* Assign extra_data fields in response structure */ @@ -938,21 +931,22 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) /* Parse domain and username */ parse_domain_user(state->request.data.username, - name_domain, name_user); - - /* bail if there is no domain */ + name_domain, name_user); - if ( !*name_domain ) - goto done; - /* Get info for the domain */ if ((domain = find_domain_from_name(name_domain)) == NULL) { - DEBUG(0, ("could not find domain entry for domain %s\n", + DEBUG(7, ("could not find domain entry for domain %s\n", name_domain)); goto done; } + if ( domain->primary && lp_winbind_trusted_domains_only()) { + DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getgroups() for %s\\%s.\n", + name_domain, name_user)); + return WINBINDD_ERROR; + } + /* Get rid and name type from name. The following costs 1 packet */ if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid, @@ -961,7 +955,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; } - if (name_type != SID_NAME_USER) { + if (name_type != SID_NAME_USER && name_type != SID_NAME_COMPUTER) { DEBUG(1, ("name '%s' is not a user name: %d\n", name_user, name_type)); goto done; @@ -1000,7 +994,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) in a win2k native mode domain. */ if ( !((sid_type==SID_NAME_DOM_GRP) || - ((sid_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) ) + ((sid_type==SID_NAME_ALIAS) && domain->primary)) ) { DEBUG(10, ("winbindd_getgroups: sid type %d " "for %s is not a domain group\n", @@ -1127,7 +1121,7 @@ enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state) sid_string_static(&user_sid))); goto done; } - + status = domain->methods->lookup_usergroups(domain, mem_ctx, &user_sid, &num_groups, &user_grpsids); diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c index 08b5be827d..18478992f3 100644 --- a/source3/nsswitch/winbindd_misc.c +++ b/source3/nsswitch/winbindd_misc.c @@ -36,7 +36,6 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat int num_retries = 0; struct cli_state *cli; uint32 sec_channel_type; - const char *contact_domain_name = NULL; struct winbindd_domain *contact_domain; DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid)); @@ -51,18 +50,10 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat } - /* use the realm name if appropriate and possible */ - - if ( lp_security() == SEC_ADS ) - contact_domain_name = lp_realm(); - - if ( !contact_domain_name || !*contact_domain_name ) - contact_domain_name = lp_workgroup(); - - contact_domain = find_domain_from_name(contact_domain_name); + contact_domain = find_our_domain(); if (!contact_domain) { result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - DEBUG(1, ("%s is not a trusted domain\n", contact_domain_name)); + DEBUG(1, ("Cannot find our own domain!\n")); goto done; } @@ -132,7 +123,7 @@ enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state /* Skip own domain */ - if (strequal(domain->name, lp_workgroup())) continue; + if (domain->primary) continue; /* Add domain to list */ @@ -232,6 +223,7 @@ enum winbindd_result winbindd_domain_info(struct winbindd_cli_state *state) sid_string_static(&domain->sid)); state->response.data.domain_info.native_mode = domain->native_mode; + state->response.data.domain_info.active_directory = domain->active_directory; state->response.data.domain_info.primary = domain->primary; state->response.data.domain_info.sequence_number = diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index 0dd00e9b39..0d110b8afa 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -36,7 +36,7 @@ /* Update this when you change the interface. */ -#define WINBIND_INTERFACE_VERSION 8 +#define WINBIND_INTERFACE_VERSION 9 /* Socket commands */ @@ -272,6 +272,7 @@ struct winbindd_response { fstring alt_name; fstring sid; BOOL native_mode; + BOOL active_directory; BOOL primary; uint32 sequence_number; } domain_info; diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index f619aa3564..21e0c3092e 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -950,7 +950,8 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid) NTSTATUS result = NT_STATUS_UNSUCCESSFUL; TALLOC_CTX *mem_ctx; CLI_POLICY_HND *hnd; - fstring level5_dom; + char *level5_dom; + DOM_SID *alloc_sid; int retry; DEBUG(3,("rpc: domain_sid\n")); @@ -965,9 +966,17 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid) goto done; result = cli_lsa_query_info_policy(hnd->cli, mem_ctx, - &hnd->pol, 0x05, level5_dom, sid); + &hnd->pol, 0x05, &level5_dom, &alloc_sid); } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1); + if (NT_STATUS_IS_OK(result)) { + if (alloc_sid) { + sid_copy(sid, alloc_sid); + } else { + result = NT_STATUS_NO_MEMORY; + } + } + done: talloc_destroy(mem_ctx); return result; diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index 7c4c8d804a..9fbf47046d 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -152,7 +152,7 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) DOM_SID sid2; uint32 rid; - domain = find_domain_from_name( lp_workgroup() ); + domain = find_our_domain(); if ( !domain ) { DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n")); return WINBINDD_ERROR; @@ -244,7 +244,7 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) uint32 rid; unid_t id; - domain = find_domain_from_name( lp_workgroup() ); + domain = find_our_domain(); if ( !domain ) { DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n")); return WINBINDD_ERROR; @@ -341,7 +341,7 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) if ( !(pw = getpwuid(state->request.data.uid)) ) return WINBINDD_ERROR; - if ( !(domain = find_domain_from_name(lp_workgroup())) ) { + if ( !(domain = find_our_domain()) ) { DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n")); return WINBINDD_ERROR; } @@ -411,7 +411,7 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) if ( !(grp = getgrgid(state->request.data.gid)) ) return WINBINDD_ERROR; - if ( !(domain = find_domain_from_name(lp_workgroup())) ) { + if ( !(domain = find_our_domain()) ) { DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n")); return WINBINDD_ERROR; } diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index 903a2a8bfa..d08377c888 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -37,7 +37,8 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, char *full_name, struct winbindd_pw *pw) { fstring output_username; - pstring homedir; + char *homedir; + char *shell; fstring sid_string; if (!pw || !dom_name || !user_name) @@ -72,24 +73,32 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, shell. */ /* The substitution of %U and %D in the 'template homedir' is done - by lp_string() calling standard_sub_basic(). */ + by alloc_sub_specified() below. */ - fstrcpy(current_user_info.smb_name, user_name); - sub_set_smb_name(user_name); fstrcpy(current_user_info.domain, dom_name); - pstrcpy(homedir, lp_template_homedir()); + homedir = alloc_sub_specified(lp_template_homedir(), user_name, dom_name, pw->pw_uid, pw->pw_gid); + + if (!homedir) + return False; safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1); - safe_strcpy(pw->pw_shell, lp_template_shell(), + SAFE_FREE(homedir); + + shell = alloc_sub_specified(lp_template_shell(), user_name, dom_name, pw->pw_uid, pw->pw_gid); + + if (!shell) + return False; + + safe_strcpy(pw->pw_shell, shell, sizeof(pw->pw_shell) - 1); /* Password - set to "x" as we can't generate anything useful here. Authentication can be done using the pam_winbind module. */ safe_strcpy(pw->pw_passwd, "x", sizeof(pw->pw_passwd) - 1); - + return True; } @@ -115,7 +124,7 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) /* Parse domain and username */ parse_domain_user(state->request.data.username, - name_domain, name_user); + name_domain, name_user); /* if this is our local domain (or no domain), the do a local tdb search */ @@ -131,17 +140,17 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) /* should we deal with users for our domain? */ - if ( lp_winbind_trusted_domains_only() && strequal(name_domain, lp_workgroup())) { - DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n", - name_domain, name_user)); - return WINBINDD_ERROR; - } - if ((domain = find_domain_from_name(name_domain)) == NULL) { DEBUG(5, ("no such domain: %s\n", name_domain)); return WINBINDD_ERROR; } + if ( domain->primary && lp_winbind_trusted_domains_only()) { + DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n", + name_domain, name_user)); + return WINBINDD_ERROR; + } + /* Get rid and name type from name */ if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid, &name_type)) { @@ -149,15 +158,13 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - if (name_type != SID_NAME_USER) { + if (name_type != SID_NAME_USER && name_type != SID_NAME_COMPUTER) { DEBUG(1, ("name '%s' is not a user name: %d\n", name_user, name_type)); return WINBINDD_ERROR; } - /* Get some user info. Split the user rid from the sid obtained - from the winbind_lookup_by_name() call and use it in a - winbind_lookup_userinfo() */ + /* Get some user info. */ if (!(mem_ctx = talloc_init("winbindd_getpwnam([%s]\\[%s])", name_domain, name_user))) { @@ -530,15 +537,6 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) name_list = ent->sam_entries; - /* Skip machine accounts */ - - if (name_list[ent->sam_entry_index]. - name[strlen(name_list[ent->sam_entry_index].name) - 1] - == '$') { - ent->sam_entry_index++; - continue; - } - /* Lookup user info */ result = winbindd_fill_pwent( diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 4cc43e85d6..076ab1a2fc 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -49,6 +49,14 @@ static const fstring name_deadbeef = ""; static struct winbindd_domain *_domain_list; +/** + When was the last scan of trusted domains done? + + 0 == not ever +*/ + +static time_t last_trustdom_scan; + struct winbindd_domain *domain_list(void) { /* Initialise list */ @@ -83,6 +91,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const { struct winbindd_domain *domain; const char *alternative_name = NULL; + static const DOM_SID null_sid; /* ignore alt_name if we are not in an AD domain */ @@ -103,6 +112,13 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const return domain; } } + if (sid) { + if (sid_equal(sid, &null_sid) ) { + + } else if (sid_equal(sid, &domain->sid)) { + return domain; + } + } } /* Create new domain entry */ @@ -133,12 +149,14 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const sid_copy(&domain->sid, sid); } - /* see if this is a native mode win2k domain */ + /* set flags about native_mode, active_directory */ - domain->native_mode = cm_check_for_native_mode_win2k( domain ); + set_dc_type_and_flags( domain ); - DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain->name, - domain->native_mode ? "native" : "mixed (or NT4)" )); + DEBUG(3,("add_trusted_domain: %s is an %s %s domain\n", domain->name, + domain->active_directory ? "ADS" : "NT4", + domain->native_mode ? "native mode" : + ((domain->active_directory && !domain->native_mode) ? "mixed mode" : ""))); /* Link to domain list */ DLIST_ADD(_domain_list, domain); @@ -156,13 +174,12 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const void rescan_trusted_domains( void ) { - static time_t last_scan; time_t now = time(NULL); struct winbindd_domain *mydomain = NULL; /* see if the time has come... */ - if ( (now > last_scan) && ((now-last_scan) < WINBINDD_RESCAN_FREQ) ) + if ( (now > last_trustdom_scan) && ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) ) return; if ( (mydomain = find_our_domain()) == NULL ) { @@ -174,7 +191,7 @@ void rescan_trusted_domains( void ) add_trusted_domains( mydomain ); - last_scan = now; + last_trustdom_scan = now; return; } @@ -200,7 +217,7 @@ void add_trusted_domains( struct winbindd_domain *domain ) return; } - DEBUG(1, ("scanning trusted domain list\n")); + DEBUG(5, ("scanning trusted domain list\n")); if (!(mem_ctx = talloc_init("init_domain_list"))) return; @@ -221,7 +238,7 @@ void add_trusted_domains( struct winbindd_domain *domain ) for(i = 0; i < num_domains; i++) { DEBUG(10,("Found domain %s\n", names[i])); add_trusted_domain(names[i], alt_names?alt_names[i]:NULL, - domain->methods, &dom_sids[i]); + domain->methods, &dom_sids[i]); /* if the SID was empty, we better set it now */ @@ -263,7 +280,7 @@ BOOL init_domain_list(void) /* Free existing list */ free_domain_list(); - /* Add ourselves as the first entry. It *must* be the first entry */ + /* Add ourselves as the first entry. */ domain = add_trusted_domain( lp_workgroup(), lp_realm(), &cache_methods, NULL); @@ -286,7 +303,9 @@ BOOL init_domain_list(void) /* do an initial scan for trusted domains */ add_trusted_domains(domain); - + + /* avoid rescanning this right away */ + last_trustdom_scan = time(NULL); return True; } @@ -364,10 +383,6 @@ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, { NTSTATUS result; TALLOC_CTX *mem_ctx; - /* Don't bother with machine accounts */ - - if (name[strlen(name) - 1] == '$') - return False; mem_ctx = talloc_init("lookup_sid_by_name for %s\n", name); if (!mem_ctx) diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c index 779d1b2c6c..100a103924 100644 --- a/source3/nsswitch/wins.c +++ b/source3/nsswitch/wins.c @@ -194,7 +194,7 @@ int lookup(nsd_file_t *rq) * response needs to be a string of the following format * ip_address[ ip_address]*\tname[ alias]* */ - if (strcasecmp(map,"hosts.byaddr") == 0) { + if (StrCaseCmp(map,"hosts.byaddr") == 0) { if ( status = lookup_byaddr_backend(key, &count)) { size = strlen(key) + 1; if (size > len) { @@ -222,7 +222,7 @@ int lookup(nsd_file_t *rq) response[strlen(response)-1] = '\n'; free(status); } - } else if (strcasecmp(map,"hosts.byname") == 0) { + } else if (StrCaseCmp(map,"hosts.byname") == 0) { if (ip_list = lookup_byname_backend(key, &count)) { for (i = count; i ; i--) { addr = inet_ntoa(ip_list[i-1]); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 67012ee087..a1fb90157c 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -217,6 +217,7 @@ typedef struct int change_notify_timeout; int map_to_guest; int min_passwd_length; + BOOL use_cracklib; int oplock_break_wait_time; int winbind_cache_time; int iLockSpinCount; @@ -749,6 +750,12 @@ static const struct enum_list enum_map_to_guest[] = { * Any parameter that does NOT have FLAG_ADVANCED will not disply at all * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in * respective views. + * + * NOTE2: Handling of duplicated (synonym) paramters: + * Only the first occurance of a parameter should be enabled by FLAG_BASIC + * and/or FLAG_ADVANCED. All duplicates following the first mention should be + * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred + * name first, and all synonyms must follow it with the FLAG_HIDE attribute. */ static struct parm_struct parm_table[] = { @@ -784,6 +791,7 @@ static struct parm_struct parm_table[] = { {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED}, {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED}, {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED}, + {"use cracklib", P_BOOL, P_GLOBAL, &Globals.use_cracklib, NULL, NULL, FLAG_ADVANCED}, {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED}, {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED}, {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED}, @@ -1153,9 +1161,9 @@ static struct parm_struct parm_table[] = { {"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_DEPRECATED}, {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED}, {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED}, - {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED}, + {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE}, {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED}, - {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED}, + {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE}, {"template primary group", P_STRING, P_GLOBAL, &Globals.szTemplatePrimaryGroup, NULL, NULL, FLAG_ADVANCED}, {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED}, {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED}, @@ -1437,6 +1445,7 @@ static void init_globals(void) Globals.map_to_guest = 0; /* By Default, "Never" */ Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */ + Globals.use_cracklib = False; Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */ Globals.enhanced_browsing = True; Globals.iLockSpinCount = 3; /* Try 3 times. */ @@ -1681,8 +1690,8 @@ FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript) FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook) FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners) FN_GLOBAL_STRING(lp_template_primary_group, &Globals.szTemplatePrimaryGroup) -FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir) -FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell) +FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir) +FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell) FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator) FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat) FN_GLOBAL_BOOL(lp_winbind_enable_local_accounts, &Globals.bWinbindEnableLocalAccounts) @@ -1791,6 +1800,7 @@ FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout) FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest) FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length) +FN_GLOBAL_BOOL(lp_use_cracklib, &Globals.use_cracklib) FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time) FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount) FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime) diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index a5a2c29a8b..f9557cac42 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -3,6 +3,7 @@ Copyright (C) Andrew Tridgell 1992-2001 Copyright (C) Andrew Bartlett 2002 Copyright (C) Rafal Szczesniak 2002 + Copyright (C) Tim Potter 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 @@ -790,3 +791,40 @@ BOOL secrets_fetch_afs_key(const char *cell, struct afs_key *result) return True; } + +/****************************************************************************** + When kerberos is not available, choose between anonymous or + authenticated connections. + + We need to use an authenticated connection if DCs have the + RestrictAnonymous registry entry set > 0, or the "Additional + restrictions for anonymous connections" set in the win2k Local + Security Policy. + + Caller to free() result in domain, username, password +*******************************************************************************/ +void secrets_fetch_ipc_userpass(char **username, char **domain, char **password) +{ + *username = secrets_fetch(SECRETS_AUTH_USER, NULL); + *domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL); + *password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL); + + if (*username && **username) { + + if (!*domain || !**domain) + *domain = smb_xstrdup(lp_workgroup()); + + if (!*password || !**password) + *password = smb_xstrdup(""); + + DEBUG(3, ("IPC$ connections done by user %s\\%s\n", + *domain, *username)); + + } else { + DEBUG(3, ("IPC$ connections done anonymously\n")); + *username = smb_xstrdup(""); + *domain = smb_xstrdup(""); + *password = smb_xstrdup(""); + } +} + diff --git a/source3/printing/notify.c b/source3/printing/notify.c index f2dd7d4f22..7750239630 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "printing.h" static TALLOC_CTX *send_ctx; diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index 77719ffc52..f0096a17c2 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -18,6 +18,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "printing.h" #ifdef HAVE_CUPS diff --git a/source3/printing/print_generic.c b/source3/printing/print_generic.c index 1c847448da..9e0ea85bb9 100644 --- a/source3/printing/print_generic.c +++ b/source3/printing/print_generic.c @@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "printing.h" diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 791c41fe69..bdcd950450 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "printing.h" /* Current printer interface */ diff --git a/source3/printing/printing_db.c b/source3/printing/printing_db.c index 1c7ac71353..0e0fb1b51d 100644 --- a/source3/printing/printing_db.c +++ b/source3/printing/printing_db.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "printing.h" static struct tdb_print_db *print_db_head; diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 0ec9beb1a4..40b83c5c0c 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -443,7 +443,7 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint16 info_class, - fstring domain_name, DOM_SID *domain_sid) + char **domain_name, DOM_SID **domain_sid) { prs_struct qbuf, rbuf; LSA_Q_QUERY_INFO q; @@ -481,39 +481,40 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - ZERO_STRUCTP(domain_sid); - domain_name[0] = '\0'; - switch (info_class) { case 3: - if (r.dom.id3.buffer_dom_name != 0) { - unistr2_to_ascii(domain_name, - &r.dom.id3. - uni_domain_name, - sizeof (fstring) - 1); + if (domain_name && (r.dom.id3.buffer_dom_name != 0)) { + *domain_name = unistr2_tdup(mem_ctx, + &r.dom.id3. + uni_domain_name); } - if (r.dom.id3.buffer_dom_sid != 0) { - *domain_sid = r.dom.id3.dom_sid.sid; + if (domain_sid && (r.dom.id3.buffer_dom_sid != 0)) { + *domain_sid = talloc(mem_ctx, sizeof(**domain_sid)); + if (*domain_sid) { + sid_copy(*domain_sid, &r.dom.id3.dom_sid.sid); + } } break; case 5: - if (r.dom.id5.buffer_dom_name != 0) { - unistr2_to_ascii(domain_name, &r.dom.id5. - uni_domain_name, - sizeof (fstring) - 1); + if (domain_name && (r.dom.id5.buffer_dom_name != 0)) { + *domain_name = unistr2_tdup(mem_ctx, + &r.dom.id5. + uni_domain_name); } - if (r.dom.id5.buffer_dom_sid != 0) { - *domain_sid = r.dom.id5.dom_sid.sid; + if (domain_sid && (r.dom.id5.buffer_dom_sid != 0)) { + *domain_sid = talloc(mem_ctx, sizeof(**domain_sid)); + if (*domain_sid) { + sid_copy(*domain_sid, &r.dom.id5.dom_sid.sid); + } } - break; - + default: DEBUG(3, ("unknown info class %d\n", info_class)); break; @@ -536,10 +537,9 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_lsa_query_info_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint16 info_class, - fstring domain_name, fstring dns_name, - fstring forest_name, - struct uuid *domain_guid, - DOM_SID *domain_sid) + char **domain_name, char **dns_name, + char **forest_name, struct uuid **domain_guid, + DOM_SID **domain_sid) { prs_struct qbuf, rbuf; LSA_Q_QUERY_INFO2 q; @@ -580,30 +580,37 @@ NTSTATUS cli_lsa_query_info_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - ZERO_STRUCTP(domain_sid); ZERO_STRUCTP(domain_guid); - domain_name[0] = '\0'; - if (r.info.dns_dom_info.hdr_nb_dom_name.buffer) { - unistr2_to_ascii(domain_name, - &r.info.dns_dom_info.uni_nb_dom_name, - sizeof(fstring) - 1); + if (domain_name && r.info.dns_dom_info.hdr_nb_dom_name.buffer) { + *domain_name = unistr2_tdup(mem_ctx, + &r.info.dns_dom_info + .uni_nb_dom_name); } - if (r.info.dns_dom_info.hdr_dns_dom_name.buffer) { - unistr2_to_ascii(dns_name, - &r.info.dns_dom_info.uni_dns_dom_name, - sizeof(fstring) - 1); + if (dns_name && r.info.dns_dom_info.hdr_dns_dom_name.buffer) { + *dns_name = unistr2_tdup(mem_ctx, + &r.info.dns_dom_info + .uni_dns_dom_name); } - if (r.info.dns_dom_info.hdr_forest_name.buffer) { - unistr2_to_ascii(forest_name, - &r.info.dns_dom_info.uni_forest_name, - sizeof(fstring) - 1); + if (forest_name && r.info.dns_dom_info.hdr_forest_name.buffer) { + *forest_name = unistr2_tdup(mem_ctx, + &r.info.dns_dom_info + .uni_forest_name); } - memcpy(domain_guid, &r.info.dns_dom_info.dom_guid,sizeof(struct uuid)); - - if (r.info.dns_dom_info.ptr_dom_sid != 0) { - *domain_sid = r.info.dns_dom_info.dom_sid.sid; + if (domain_guid) { + *domain_guid = talloc(mem_ctx, sizeof(**domain_guid)); + memcpy(*domain_guid, + &r.info.dns_dom_info.dom_guid, + sizeof(struct uuid)); + } + + if (domain_sid && r.info.dns_dom_info.ptr_dom_sid != 0) { + *domain_sid = talloc(mem_ctx, sizeof(**domain_sid)); + if (*domain_sid) { + sid_copy(*domain_sid, + &r.info.dns_dom_info.dom_sid.sid); + } } done: diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index b9974cba8a..7edd34c8dd 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2834,11 +2834,17 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid) DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n")); } else { /* update the UNIX password */ - if (lp_unix_password_sync() ) - if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) { + if (lp_unix_password_sync() ) { + struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd)); + if (!passwd) { + DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n")); + } + + if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) { pdb_free_sam(&pwd); return False; } + } } ZERO_STRUCT(plaintext_buf); @@ -2899,7 +2905,12 @@ static BOOL set_user_info_pw(char *pass, DOM_SID *sid) } else { /* update the UNIX password */ if (lp_unix_password_sync()) { - if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) { + struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd)); + if (!passwd) { + DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n")); + } + + if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) { pdb_free_sam(&pwd); return False; } diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 217e6b1d68..d9afde465d 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -68,9 +68,13 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_SID dom_sid; - struct uuid dom_guid; - fstring sid_str, domain_name="", dns_name="", forest_name=""; + DOM_SID *dom_sid; + struct uuid *dom_guid; + fstring sid_str; + char *domain_name = NULL; + char *dns_name = NULL; + char *forest_name = NULL; + uint32 info_class = 3; if (argc > 2) { @@ -91,8 +95,8 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, if (!NT_STATUS_IS_OK(result)) goto done; result = cli_lsa_query_info_policy2(cli, mem_ctx, &pol, - info_class, domain_name, - dns_name, forest_name, + info_class, &domain_name, + &dns_name, &forest_name, &dom_guid, &dom_sid); break; default: @@ -103,28 +107,28 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, if (!NT_STATUS_IS_OK(result)) goto done; result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, - info_class, domain_name, + info_class, &domain_name, &dom_sid); } if (!NT_STATUS_IS_OK(result)) goto done; + + sid_to_string(sid_str, dom_sid); - sid_to_string(sid_str, &dom_sid); - - if (domain_name[0]) + if (domain_name) printf("domain %s has sid %s\n", domain_name, sid_str); else printf("could not query info for level %d\n", info_class); - if (dns_name[0]) + if (dns_name) printf("domain dns name is %s\n", dns_name); - if (forest_name[0]) + if (forest_name) printf("forest name is %s\n", forest_name); if (info_class == 12) { - printf("domain GUID is %s\n", - smb_uuid_string_static(dom_guid)); + printf("domain GUID is "); + smb_uuid_string_static(*dom_guid); } done: return result; diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 798949fae9..f5a440c024 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1336,7 +1336,7 @@ static WERROR cmd_spoolss_addprinterex(struct cli_state *cli, slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost); strupper_m(servername); - /* Fill in the DRIVER_INFO_3 struct */ + /* Fill in the DRIVER_INFO_2 struct */ ZERO_STRUCT(info2); #if 0 /* JERRY */ init_unistr( &info2.servername, servername); diff --git a/source3/script/installswat.sh b/source3/script/installswat.sh index 027ca35110..c0285bda55 100755 --- a/source3/script/installswat.sh +++ b/source3/script/installswat.sh @@ -71,7 +71,7 @@ for ln in $LANGS; do done -# Install html documentation +# Install html documentation (if html documentation tree is here) if [ -d $SRCDIR../docs/htmldocs/ ]; then diff --git a/source3/script/mkbuildoptions.awk b/source3/script/mkbuildoptions.awk index cdc5bd9881..9c22662310 100644 --- a/source3/script/mkbuildoptions.awk +++ b/source3/script/mkbuildoptions.awk @@ -242,14 +242,14 @@ END { # add code to display the various type sizes print " /* Output the sizes of the various types */"; print " output(screen, \"\\nType sizes:\\n\");"; - print " output(screen, \" sizeof(char): %u\\n\",sizeof(char));"; - print " output(screen, \" sizeof(int): %u\\n\",sizeof(int));"; - print " output(screen, \" sizeof(long): %u\\n\",sizeof(long));"; - print " output(screen, \" sizeof(uint8): %u\\n\",sizeof(uint8));"; - print " output(screen, \" sizeof(uint16): %u\\n\",sizeof(uint16));"; - print " output(screen, \" sizeof(uint32): %u\\n\",sizeof(uint32));"; - print " output(screen, \" sizeof(short): %u\\n\",sizeof(short));"; - print " output(screen, \" sizeof(void*): %u\\n\",sizeof(void*));"; + print " output(screen, \" sizeof(char): %lu\\n\",(unsigned long)sizeof(char));"; + print " output(screen, \" sizeof(int): %lu\\n\",(unsigned long)sizeof(int));"; + print " output(screen, \" sizeof(long): %lu\\n\",(unsigned long)sizeof(long));"; + print " output(screen, \" sizeof(uint8): %lu\\n\",(unsigned long)sizeof(uint8));"; + print " output(screen, \" sizeof(uint16): %lu\\n\",(unsigned long)sizeof(uint16));"; + print " output(screen, \" sizeof(uint32): %lu\\n\",(unsigned long)sizeof(uint32));"; + print " output(screen, \" sizeof(short): %lu\\n\",(unsigned long)sizeof(short));"; + print " output(screen, \" sizeof(void*): %lu\\n\",(unsigned long)sizeof(void*));"; ################################################## # add code to give information about modules diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index e6117245e7..692e82680d 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -49,6 +49,16 @@ #include "includes.h" +#ifdef HAVE_WORKING_CRACKLIB +#include + +#ifndef HAVE_CRACKLIB_DICTPATH +#ifndef CRACKLIB_DICTPATH +#define CRACKLIB_DICTPATH SAMBA_CRACKLIB_DICTPATH +#endif +#endif +#endif + extern struct passdb_ops pdb_ops; static NTSTATUS check_oem_password(const char *user, @@ -441,25 +451,14 @@ while we were waiting\n", WTERMSIG(wstat))); return (chstat); } -BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL as_root) +BOOL chgpasswd(const char *name, const struct passwd *pass, + const char *oldpass, const char *newpass, BOOL as_root) { pstring passwordprogram; pstring chatsequence; size_t i; size_t len; - struct passwd *pass; - - if (!name) { - DEBUG(1, ("chgpasswd: NULL username specfied !\n")); - } - - pass = Get_Pwnam(name); - if (!pass) { - DEBUG(1, ("chgpasswd: Username does not exist in system !\n")); - return False; - } - if (!oldpass) { oldpass = ""; } @@ -471,13 +470,6 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL #endif /* Take the passed information and test it for minimum criteria */ - /* Minimum password length */ - if (strlen(newpass) < lp_min_passwd_length()) { - /* too short, must be at least MINPASSWDLENGTH */ - DEBUG(0, ("chgpasswd: Password Change: user %s, New password is shorter than minimum password length = %d\n", - name, lp_min_passwd_length())); - return (False); /* inform the user */ - } /* Password is same as old password */ if (strcmp(oldpass, newpass) == 0) { @@ -570,7 +562,8 @@ the string %%u, and the given string %s does not.\n", passwordprogram )); #else /* ALLOW_CHANGE_PASSWORD */ -BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL as_root) +BOOL chgpasswd(const char *name, const struct passwd *pass, + const char *oldpass, const char *newpass, BOOL as_root) { DEBUG(0, ("chgpasswd: Password changing not compiled in (user=%s)\n", name)); return (False); @@ -909,6 +902,8 @@ static NTSTATUS check_oem_password(const char *user, NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd, BOOL as_root) { + struct passwd *pass; + BOOL ret; uint32 min_len; @@ -936,7 +931,47 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw /* return NT_STATUS_PWD_TOO_SHORT; */ } - /* TODO: Add cracklib support here */ + pass = Get_Pwnam(pdb_get_username(hnd)); + if (!pass) { + DEBUG(1, ("check_oem_password: Username does not exist in system !?!\n")); + } + +#ifdef HAVE_WORKING_CRACKLIB + if (pass) { + /* if we can, become the user to overcome internal cracklib sillyness */ + if (!push_sec_ctx()) + return NT_STATUS_UNSUCCESSFUL; + + set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL); + set_re_uid(); + } + + if (lp_use_cracklib()) { + const char *crack_check_reason; + DEBUG(4, ("change_oem_password: Checking password for user [%s]" + " against cracklib. \n", pdb_get_username(hnd))); + DEBUGADD(4, ("If this is your last message, then something is " + "wrong with cracklib, it might be missing it's " + "dictionaries at %s\n", + CRACKLIB_DICTPATH)); + dbgflush(); + + crack_check_reason = FascistCheck(new_passwd, (char *)CRACKLIB_DICTPATH); + if (crack_check_reason) { + DEBUG(1, ("Password Change: user [%s], " + "New password failed cracklib test - %s\n", + pdb_get_username(hnd), crack_check_reason)); + + /* get back to where we should be */ + if (pass) + pop_sec_ctx(); + return NT_STATUS_PASSWORD_RESTRICTION; + } + } + + if (pass) + pop_sec_ctx(); +#endif /* * If unix password sync was requested, attempt to change @@ -951,7 +986,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw */ if(lp_unix_password_sync() && - !chgpasswd(pdb_get_username(hnd), old_passwd, new_passwd, as_root)) { + !chgpasswd(pdb_get_username(hnd), pass, old_passwd, new_passwd, as_root)) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c index 46f688a219..19f225e973 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -50,33 +50,16 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B #ifdef LINUX #include -#include +#include /* * This shouldn't be neccessary - it should be /usr/include/sys/quota.h - * Unfortunately, RH7.1 ships with a different quota system using struct mem_dqblk - * rather than the struct dqblk defined in /usr/include/sys/quota.h. - * This means we must include linux/quota.h to have a hope of working on - * RH7.1 systems. And it also means this breaks if the kernel is upgraded - * to a Linus 2.4.x (where x > the minor number shipped with RH7.1) until - * Linus synchronises with the AC patches. Sometimes I *hate* Linux :-). JRA. + * So we include all the files has *should* be in the system into a large, + * grungy samba_linux_quoatas.h Sometimes I *hate* Linux :-). JRA. */ -#include -#ifdef HAVE_LINUX_XQM_H -#include -#else -#ifdef HAVE_XFS_XQM_H -#include -#define HAVE_LINUX_XQM_H -#endif -#endif - -#include -#include - - -#define LINUX_QUOTAS_2 +#include "samba_linux_quota.h" +#include "samba_xfs_quota.h" typedef struct _LINUX_SMB_DISK_QUOTA { SMB_BIG_UINT bsize; @@ -92,22 +75,20 @@ typedef struct _LINUX_SMB_DISK_QUOTA { Abstract out the XFS Quota Manager quota get call. ****************************************************************************/ -static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp) +static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp) { - int ret = -1; -#ifdef HAVE_LINUX_XQM_H struct fs_disk_quota D; + int ret; ZERO_STRUCT(D); - ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); + ret = quotactl(QCMD(Q_XGETQUOTA,XFS_USER_QUOTA), path, euser_id, (caddr_t)&D); - /* As XFS has group quotas, if getting the user quota fails, try getting the group instead. */ - if (ret) { - ret = quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), path, getegid(), (caddr_t)&D); - if (ret) - return ret; - } + if (ret) + ret = quotactl(QCMD(Q_XGETQUOTA,XFS_GROUP_QUOTA), path, egrp_id, (caddr_t)&D); + + if (ret) + return ret; dp->bsize = (SMB_BIG_UINT)512; dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit; @@ -116,7 +97,7 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit; dp->curinodes = (SMB_BIG_UINT)D.d_icount; dp->curblocks = (SMB_BIG_UINT)D.d_bcount; -#endif + return ret; } @@ -124,48 +105,90 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU Abstract out the old and new Linux quota get calls. ****************************************************************************/ -static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp) +static int get_smb_linux_v1_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp) { - int ret = 0; -#ifdef LINUX_QUOTAS_1 - struct dqblk D; + struct v1_kern_dqblk D; + int ret; + ZERO_STRUCT(D); - dp->bsize = (SMB_BIG_UINT)1024; -#else /* LINUX_QUOTAS_2 */ - struct mem_dqblk D; + + ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); + + if (ret && errno != EDQUOT) + ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D); + + if (ret && errno != EDQUOT) + return ret; + + dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; + dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; + dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; + dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; + dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; + dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks; + + return ret; +} + +static int get_smb_linux_v2_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp) +{ + struct v2_kern_dqblk D; + int ret; + ZERO_STRUCT(D); -#ifndef QUOTABLOCK_SIZE -#define QUOTABLOCK_SIZE 1024 -#endif + + ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); + + if (ret && errno != EDQUOT) + ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D); + + if (ret && errno != EDQUOT) + return ret; + dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; -#endif + dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; + dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; + dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; + dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; + dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; + dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace) / dp->bsize; + + return ret; +} + +/**************************************************************************** + Brand-new generic quota interface. +****************************************************************************/ + +static int get_smb_linux_gen_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp) +{ + struct if_dqblk D; + int ret; + + ZERO_STRUCT(D); ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); - /* Linux can have group quotas, if getting the user quota fails, try getting the group instead. */ - if (ret) { - ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, getegid(), (caddr_t)&D); - if (ret) - return ret; - } + if (ret && errno != EDQUOT) + ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D); + if (ret && errno != EDQUOT) + return ret; + + dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; - -#ifdef LINUX_QUOTAS_1 - dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks; -#else /* LINUX_QUOTAS_2 */ - dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace)/ dp->bsize; -#endif + dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace) / dp->bsize; return ret; } /**************************************************************************** -try to get the disk space from disk quotas (LINUX version) + Try to get the disk space from disk quotas (LINUX version). ****************************************************************************/ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) @@ -178,9 +201,11 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB SMB_DEV_T devno; int found; uid_t euser_id; + gid_t egrp_id; euser_id = geteuid(); - + egrp_id = getegid(); + /* find the block device file */ if ( sys_stat(path, &S) == -1 ) @@ -208,10 +233,18 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB save_re_uid(); set_effective_uid(0); - if (strcmp(mnt->mnt_type, "xfs") == 0) - r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D); - else - r=get_smb_linux_vfs_quota(mnt->mnt_fsname, euser_id, &D); + + if (strcmp(mnt->mnt_type, "xfs")==0) { + r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, egrp_id, &D); + } else { + r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, egrp_id, &D); + if (r == -1 && errno != EDQUOT) { + r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, egrp_id, &D); + if (r == -1 && errno != EDQUOT) + r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, egrp_id, &D); + } + } + restore_re_uid(); /* Use softlimit to determine disk space, except when it has been exceeded */ @@ -920,8 +953,8 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1)<0)) #else if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0)) -#endif /* ifdef HPUX */ return (False); +#endif /* ifdef HPUX */ #endif /* !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) */ diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index c98b0936ed..ff70750385 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -853,6 +853,8 @@ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length, tdb_off rec_ptr, last_ptr, newrec_ptr; struct list_struct newrec; + memset(&newrec, '\0', sizeof(newrec)); + if (tdb_lock(tdb, -1, F_WRLCK) == -1) return 0; diff --git a/source3/tests/crack.c b/source3/tests/crack.c new file mode 100644 index 0000000000..1342887852 --- /dev/null +++ b/source3/tests/crack.c @@ -0,0 +1,5 @@ + +int main(int argc, char **argv) { + FascistCheck("Foo", CRACKLIB_DICTPATH); + return 0; +} diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index b28365274c..9f0f64edec 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -48,27 +48,14 @@ typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_C * @return The Domain SID of the remote machine. **/ -static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli) +static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx) { DOM_SID *domain_sid; POLICY_HND pol; NTSTATUS result = NT_STATUS_OK; uint32 info_class = 5; - fstring domain_name; - TALLOC_CTX *mem_ctx; + char *domain_name; - if (!(domain_sid = malloc(sizeof(DOM_SID)))){ - DEBUG(0,("net_get_remote_domain_sid: malloc returned NULL!\n")); - goto error; - } - - if (!(mem_ctx=talloc_init("net_get_remote_domain_sid"))) - { - DEBUG(0,("net_get_remote_domain_sid: talloc_init returned NULL!\n")); - goto error; - } - - if (!cli_nt_session_open (cli, PI_LSARPC)) { fprintf(stderr, "could not initialise lsa pipe\n"); goto error; @@ -82,7 +69,7 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli) } result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, - domain_name, domain_sid); + &domain_name, &domain_sid); if (!NT_STATUS_IS_OK(result)) { error: fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain); @@ -96,7 +83,6 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli) cli_lsa_close(cli, mem_ctx, &pol); cli_nt_session_close(cli); - talloc_destroy(mem_ctx); return domain_sid; } @@ -132,7 +118,7 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co return -1; } - domain_sid = net_get_remote_domain_sid(cli); + domain_sid = net_get_remote_domain_sid(cli, mem_ctx); /* Create mem_ctx */ @@ -1928,10 +1914,11 @@ static int rpc_trustdom_establish(int argc, const char **argv) POLICY_HND connect_hnd; TALLOC_CTX *mem_ctx; NTSTATUS nt_status; - DOM_SID domain_sid; + DOM_SID *domain_sid; WKS_INFO_100 wks_info; char* domain_name; + char* domain_name_pol; char* acct_name; fstring pdc_name; @@ -2052,7 +2039,7 @@ static int rpc_trustdom_establish(int argc, const char **argv) /* Querying info level 5 */ nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd, - 5 /* info level */, domain_name, + 5 /* info level */, &domain_name_pol, &domain_sid); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("LSA Query Info failed. Returned error was %s\n", @@ -2072,7 +2059,7 @@ static int rpc_trustdom_establish(int argc, const char **argv) if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer, wks_info.uni_lan_grp.uni_str_len, opt_password, - domain_sid)) { + *domain_sid)) { DEBUG(0, ("Storing password for trusted domain failed.\n")); return -1; } @@ -2163,7 +2150,7 @@ static int rpc_trustdom_list(int argc, const char **argv) struct cli_state *cli, *remote_cli; NTSTATUS nt_status; const char *domain_name = NULL; - DOM_SID queried_dom_sid; + DOM_SID *queried_dom_sid; fstring ascii_sid, padding; int ascii_dom_name_len; POLICY_HND connect_hnd; @@ -2173,7 +2160,8 @@ static int rpc_trustdom_list(int argc, const char **argv) int i, pad_len, col_len = 20; DOM_SID *domain_sids; char **trusted_dom_names; - fstring pdc_name, dummy; + fstring pdc_name; + char *dummy; /* trusting domains listing variables */ POLICY_HND domain_hnd; @@ -2222,7 +2210,7 @@ static int rpc_trustdom_list(int argc, const char **argv) /* query info level 5 to obtain sid of a domain being queried */ nt_status = cli_lsa_query_info_policy( cli, mem_ctx, &connect_hnd, 5 /* info level */, - dummy, &queried_dom_sid); + &dummy, &queried_dom_sid); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("LSA Query Info failed. Returned error was %s\n", @@ -2304,8 +2292,8 @@ static int rpc_trustdom_list(int argc, const char **argv) /* SamrOpenDomain - we have to open domain policy handle in order to be able to enumerate accounts*/ nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd, - SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, - &queried_dom_sid, &domain_hnd); + SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, + queried_dom_sid, &domain_hnd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("Couldn't open domain object. Error was %s\n", nt_errstr(nt_status))); diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 96e52964b4..74918045ee 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1072,6 +1072,7 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego) DATA_BLOB session_key_krb5; SPNEGO_DATA reply; char *reply_base64; + int retval; const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL}; ssize_t len; @@ -1093,9 +1094,9 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego) spnego.negTokenInit.mechListMIC.length); principal[spnego.negTokenInit.mechListMIC.length] = '\0'; - tkt = cli_krb5_get_ticket(principal, 0, &session_key_krb5); + retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5); - if (tkt.data == NULL) { + if (retval) { pstring user; @@ -1110,13 +1111,17 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego) pstr_sprintf(user, "%s@%s", opt_username, opt_domain); - if (kerberos_kinit_password(user, opt_password, 0) != 0) { - DEBUG(10, ("Requesting TGT failed\n")); + if ((retval = kerberos_kinit_password(user, opt_password, 0))) { + DEBUG(10, ("Requesting TGT failed: %s\n", error_message(retval))); x_fprintf(x_stdout, "NA\n"); return True; } - tkt = cli_krb5_get_ticket(principal, 0, &session_key_krb5); + retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5); + + if (retval) { + DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval))); + } } data_blob_free(&session_key_krb5); diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index eae1f97b58..8a27684a4d 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -717,7 +717,7 @@ int main(int argc, const char **argv) argc -= 2; break; case 's': /* --configfile */ - pstrcpy(dyn_CONFIGFILE, optarg); + pstrcpy(dyn_CONFIGFILE, poptGetOptArg(pc)); argc -= 2; break; default: diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c new file mode 100644 index 0000000000..92a3831752 --- /dev/null +++ b/source3/utils/smbget.c @@ -0,0 +1,574 @@ +/* + smbget: a wget-like utility with support for recursive downloading and + smb:// urls + Copyright (C) 2003-2004 Jelmer Vernooij + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "includes.h" +#include "libsmbclient.h" + +#if _FILE_OFFSET_BITS==64 +#define OFF_T_FORMAT "%lld" +#else +#define OFF_T_FORMAT "%ld" +#endif + +int columns = 0; + +time_t total_start_time = 0; +off_t total_bytes = 0; + +#define SMB_MAXPATHLEN MAXPATHLEN + +/* Number of bytes to read when checking whether local and remote file are really the same file */ +#define RESUME_CHECK_SIZE 512 +#define RESUME_DOWNLOAD_OFFSET 1024 +#define RESUME_CHECK_OFFSET RESUME_DOWNLOAD_OFFSET+RESUME_CHECK_SIZE +/* Number of bytes to read at once */ +#define SMB_DEFAULT_BLOCKSIZE 64000 + +const char *username = NULL, *password = NULL, *workgroup = NULL; +int nonprompt = 0, quiet = 0, dots = 0, keep_permissions = 0, verbose = 0; +int blocksize = SMB_DEFAULT_BLOCKSIZE; + +int smb_download_file(const char *base, const char *name, int recursive, int resume, char *outfile); + +int get_num_cols(void) +{ +#ifdef TIOCGWINSZ + struct winsize ws; + if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) { + perror("ioctl"); + return 0; + } + return ws.ws_col; +#else +#warning No support for TIOCGWINSZ + char *cols = getenv("COLUMNS"); + if(!cols) return 0; + return atoi(cols); +#endif +} + +void change_columns(int sig) +{ + columns = get_num_cols(); +} + +void human_readable(off_t s, char *buffer, int l) +{ + if(s > 1024 * 1024 * 1024) snprintf(buffer, l, "%.2fGb", 1.0 * s / (1024 * 1024 * 1024)); + else if(s > 1024 * 1024) snprintf(buffer, l, "%.2fMb", 1.0 * s / (1024 * 1024)); + else if(s > 1024) snprintf(buffer, l, "%.2fkb", 1.0 * s / 1024); + else snprintf(buffer, l, OFF_T_FORMAT"b", s); +} + +void get_auth_data(const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen) +{ + static char hasasked = 0; + char *wgtmp, *usertmp; + char tmp[128]; + + if(hasasked) return; + hasasked = 1; + + if(!nonprompt && !username) { + printf("Username for %s at %s [guest] ", shr, srv); + fgets(tmp, sizeof(tmp), stdin); + if(tmp[strlen(tmp)-1] == '\n')tmp[strlen(tmp)-1] = '\0'; + strncpy(un, tmp, unlen-1); + } else if(username) strncpy(un, username, unlen-1); + + if(!nonprompt && !password) { + char *prompt, *pass; + asprintf(&prompt, "Password for %s at %s: ", shr, srv); + pass = getpass(prompt); + free(prompt); + strncpy(pw, pass, pwlen-1); + } else if(password) strncpy(pw, password, pwlen-1); + + if(workgroup)strncpy(wg, workgroup, wglen-1); + + wgtmp = strndup(wg, wglen); + usertmp = strndup(un, unlen); + if(!quiet)printf("Using workgroup %s, %s%s\n", wgtmp, *usertmp?"user ":"guest user", usertmp); + free(wgtmp); free(usertmp); +} + +int smb_download_dir(const char *base, const char *name, int resume) +{ + char path[SMB_MAXPATHLEN]; + int dirhandle; + struct smbc_dirent *dirent; + const char *relname = name; + char *tmpname; + struct stat remotestat; + snprintf(path, SMB_MAXPATHLEN-1, "%s%s%s", base, (base[0] && name[0] && name[0] != '/' && base[strlen(base)-1] != '/')?"/":"", name); + + /* List files in directory and call smb_download_file on them */ + dirhandle = smbc_opendir(path); + if(dirhandle < 1) { + if(errno == ENOTDIR) return smb_download_file(base, name, 1, resume, NULL); + fprintf(stderr, "Can't open directory %s: %s\n", path, strerror(errno)); + return 0; + } + + while(*relname == '/')relname++; + mkdir(relname, 0755); + + tmpname = strdup(name); + + while((dirent = smbc_readdir(dirhandle))) { + char *newname; + if(!strcmp(dirent->name, ".") || !strcmp(dirent->name, ".."))continue; + asprintf(&newname, "%s/%s", tmpname, dirent->name); + switch(dirent->smbc_type) { + case SMBC_DIR: + smb_download_dir(base, newname, resume); + break; + + case SMBC_WORKGROUP: + smb_download_dir("smb://", dirent->name, resume); + break; + + case SMBC_SERVER: + smb_download_dir("smb://", dirent->name, resume); + break; + + case SMBC_FILE: + smb_download_file(base, newname, 1, resume, NULL); + break; + + case SMBC_FILE_SHARE: + smb_download_dir(base, newname, resume); + break; + + case SMBC_PRINTER_SHARE: + if(!quiet)printf("Ignoring printer share %s\n", dirent->name); + break; + + case SMBC_COMMS_SHARE: + if(!quiet)printf("Ignoring comms share %s\n", dirent->name); + break; + + case SMBC_IPC_SHARE: + if(!quiet)printf("Ignoring ipc$ share %s\n", dirent->name); + break; + + default: + fprintf(stderr, "Ignoring file '%s' of type '%d'\n", newname, dirent->smbc_type); + break; + } + free(newname); + } + free(tmpname); + + if(keep_permissions) { + if(smbc_fstat(dirhandle, &remotestat) < 0) { + fprintf(stderr, "Unable to get stats on %s on remote server\n", path); + smbc_closedir(dirhandle); + return 0; + } + + if(chmod(relname, remotestat.st_mode) < 0) { + fprintf(stderr, "Unable to change mode of local dir %s to %o\n", relname, remotestat.st_mode); + smbc_closedir(dirhandle); + return 0; + } + } + + smbc_closedir(dirhandle); + return 1; +} + +char *print_time(long t) +{ + static char buffer[100]; + int secs, mins, hours; + if(t < -1) { + strncpy(buffer, "Unknown", sizeof(buffer)); + return buffer; + } + + secs = (int)t % 60; + mins = (int)t / 60 % 60; + hours = (int)t / (60 * 60); + snprintf(buffer, sizeof(buffer)-1, "%02d:%02d:%02d", hours, mins, secs); + return buffer; +} + +void print_progress(const char *name, time_t start, time_t now, off_t start_pos, off_t pos, off_t total) +{ + double avg = 0.0; + long eta = -1; + double prcnt = 0.0; + char hpos[20], htotal[20], havg[20]; + char *status, *filename; + int len; + if(now - start)avg = 1.0 * (pos - start_pos) / (now - start); + eta = (total - pos - start_pos) / avg; + if(total)prcnt = 100.0 * pos / total; + + human_readable(pos, hpos, sizeof(hpos)); + human_readable(total, htotal, sizeof(htotal)); + human_readable(avg, havg, sizeof(havg)); + + len = asprintf(&status, "%s of %s (%.2f%%) at %s/s ETA: %s", hpos, htotal, prcnt, havg, print_time(eta)); + + if(columns) { + int required = strlen(name), available = columns - len - strlen("[] "); + if(required > available) asprintf(&filename, "...%s", name + required - available + 3); + else filename = strndup(name, available); + } else filename = strdup(name); + + fprintf(stderr, "\r[%s] %s", filename, status); + + free(filename); free(status); +} + +int smb_download_file(const char *base, const char *name, int recursive, int resume, char *outfile) { + int remotehandle, localhandle; + time_t start_time = time(NULL); + const char *newpath; + char path[SMB_MAXPATHLEN]; + char checkbuf[2][RESUME_CHECK_SIZE]; + char *readbuf = NULL; + off_t offset_download = 0, offset_check = 0, curpos = 0, start_offset = 0; + struct stat localstat, remotestat; + + snprintf(path, SMB_MAXPATHLEN-1, "%s%s%s", base, (*base && *name && name[0] != '/' && base[strlen(base)-1] != '/')?"/":"", name); + + remotehandle = smbc_open(path, O_RDONLY, 0755); + + if(remotehandle < 0) { + switch(errno) { + case EISDIR: + if(!recursive) { + fprintf(stderr, "%s is a directory. Specify -R to download recursively\n", path); + return 0; + } + smb_download_dir(base, name, resume); + return 0; + + case ENOENT: + fprintf(stderr, "%s can't be found on the remote server\n", path); + return 0; + + case ENOMEM: + fprintf(stderr, "Not enough memory\n"); + exit(1); + return 0; + + case ENODEV: + fprintf(stderr, "The share name used in %s does not exist\n", path); + return 0; + + case EACCES: + fprintf(stderr, "You don't have enough permissions to access %s\n", path); + return 0; + + default: + perror("smbc_open"); + return 0; + } + } + + if(smbc_fstat(remotehandle, &remotestat) < 0) { + fprintf(stderr, "Can't stat %s: %s\n", path, strerror(errno)); + return 0; + } + + if(outfile) newpath = outfile; + else if(!name[0]) { + newpath = strrchr(base, '/'); + if(newpath)newpath++; else newpath = base; + } else newpath = name; + + if(newpath[0] == '/')newpath++; + + /* Open local file and, if necessary, resume */ + localhandle = open(newpath, O_CREAT | O_NONBLOCK | O_RDWR | (!resume?O_EXCL:0), 0755); + if(localhandle < 0) { + fprintf(stderr, "Can't open %s: %s\n", newpath, strerror(errno)); + smbc_close(remotehandle); + return 0; + } + + fstat(localhandle, &localstat); + + start_offset = localstat.st_size; + + if(localstat.st_size && localstat.st_size == remotestat.st_size) { + if(verbose)fprintf(stderr, "%s is already downloaded completely.\n", path); + else if(!quiet)fprintf(stderr, "%s\n", path); + smbc_close(remotehandle); + close(localhandle); + return 1; + } + + if(localstat.st_size > RESUME_CHECK_OFFSET && remotestat.st_size > RESUME_CHECK_OFFSET) { + offset_download = localstat.st_size - RESUME_DOWNLOAD_OFFSET; + offset_check = localstat.st_size - RESUME_CHECK_OFFSET; + if(verbose)printf("Trying to start resume of %s at "OFF_T_FORMAT"\n" + "At the moment "OFF_T_FORMAT" of "OFF_T_FORMAT" bytes have been retrieved\n", newpath, offset_check, + localstat.st_size, remotestat.st_size); + } + + if(offset_check) { + off_t off1, off2; + /* First, check all bytes from offset_check to offset_download */ + off1 = lseek(localhandle, offset_check, SEEK_SET); + if(off1 < 0) { + fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in local file %s\n", offset_check, newpath); + smbc_close(remotehandle); close(localhandle); + return 0; + } + + off2 = smbc_lseek(remotehandle, offset_check, SEEK_SET); + if(off2 < 0) { + fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in remote file %s\n", offset_check, newpath); + smbc_close(remotehandle); close(localhandle); + return 0; + } + + if(off1 != off2) { + fprintf(stderr, "Offset in local and remote files is different (local: "OFF_T_FORMAT", remote: "OFF_T_FORMAT")\n", off1, off2); + return 0; + } + + if(smbc_read(remotehandle, checkbuf[0], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { + fprintf(stderr, "Can't read %d bytes from remote file %s\n", RESUME_CHECK_SIZE, path); + smbc_close(remotehandle); close(localhandle); + return 0; + } + + if(read(localhandle, checkbuf[1], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { + fprintf(stderr, "Can't read %d bytes from local file %s\n", RESUME_CHECK_SIZE, name); + smbc_close(remotehandle); close(localhandle); + return 0; + } + + if(memcmp(checkbuf[0], checkbuf[1], RESUME_CHECK_SIZE) == 0) { + if(verbose)printf("Current local and remote file appear to be the same. Starting download from offset "OFF_T_FORMAT"\n", offset_download); + } else { + fprintf(stderr, "Local and remote file appear to be different, not doing resume for %s\n", path); + smbc_close(remotehandle); close(localhandle); + return 0; + } + } + + readbuf = malloc(blocksize); + + /* Now, download all bytes from offset_download to the end */ + for(curpos = offset_download; curpos < remotestat.st_size; curpos+=blocksize) { + ssize_t bytesread = smbc_read(remotehandle, readbuf, blocksize); + if(bytesread < 0) { + fprintf(stderr, "Can't read %d bytes at offset "OFF_T_FORMAT", file %s\n", blocksize, curpos, path); + smbc_close(remotehandle); close(localhandle); + free(readbuf); + return 0; + } + + total_bytes += bytesread; + + if(write(localhandle, readbuf, bytesread) < 0) { + fprintf(stderr, "Can't write %d bytes to local file %s at offset "OFF_T_FORMAT"\n", bytesread, path, curpos); + free(readbuf); + smbc_close(remotehandle); close(localhandle); + return 0; + } + + if(dots)fputc('.', stderr); + else if(!quiet) { + print_progress(newpath, start_time, time(NULL), start_offset, curpos, remotestat.st_size); + } + } + + free(readbuf); + + if(dots){ + fputc('\n', stderr); + printf("%s downloaded\n", path); + } else if(!quiet) { + int i; + fprintf(stderr, "\r%s", path); + if(columns) { + for(i = strlen(path); i < columns; i++) { + fputc(' ', stderr); + } + } + fputc('\n', stderr); + } + + if(keep_permissions) { + if(fchmod(localhandle, remotestat.st_mode) < 0) { + fprintf(stderr, "Unable to change mode of local file %s to %o\n", path, remotestat.st_mode); + smbc_close(remotehandle); + close(localhandle); + return 0; + } + } + smbc_close(remotehandle); + close(localhandle); + return 1; +} + +void clean_exit(void) +{ + char bs[100]; + human_readable(total_bytes, bs, sizeof(bs)); + if(!quiet)fprintf(stderr, "Downloaded %s in %lu seconds\n", bs, time(NULL) - total_start_time); + exit(0); +} + +void signal_quit(int v) +{ + clean_exit(); +} + +int readrcfile(const char *name, const struct poptOption long_options[]) +{ + FILE *fd = fopen(name, "r"); + int lineno = 0, i; + char var[101], val[101]; + char found; + int *intdata; char **stringdata; + if(!fd) { + fprintf(stderr, "Can't open RC file %s\n", name); + return 1; + } + + while(!feof(fd)) { + lineno++; + if(fscanf(fd, "%100s %100s\n", var, val) < 2) { + fprintf(stderr, "Can't parse line %d of %s, ignoring.\n", lineno, name); + continue; + } + + found = 0; + + for(i = 0; long_options[i].shortName; i++) { + if(!long_options[i].longName)continue; + if(strcmp(long_options[i].longName, var)) continue; + if(!long_options[i].arg)continue; + + switch(long_options[i].argInfo) { + case POPT_ARG_NONE: + intdata = (int *)long_options[i].arg; + if(!strcmp(val, "on")) *intdata = 1; + else if(!strcmp(val, "off")) *intdata = 0; + else fprintf(stderr, "Illegal value %s for %s at line %d in %s\n", val, var, lineno, name); + break; + case POPT_ARG_INT: + intdata = (int *)long_options[i].arg; + *intdata = atoi(val); + break; + case POPT_ARG_STRING: + stringdata = (char **)long_options[i].arg; + *stringdata = strdup(val); + break; + default: + fprintf(stderr, "Invalid variable %s at line %d in %s\n", var, lineno, name); + break; + } + + found = 1; + } + if(!found) { + fprintf(stderr, "Invalid variable %s at line %d in %s\n", var, lineno, name); + } + } + + fclose(fd); + return 0; +} + +int main(int argc, const char **argv) +{ + int resume = 0, recursive = 0; + int c = 0; + int debuglevel = 0; + const char *file = NULL; + char *rcfile = NULL; + char *outputfile = NULL; + struct poptOption long_options[] = { + {"guest", 'a', POPT_ARG_NONE, NULL, 'a', "Work as user guest" }, + {"resume", 'r', POPT_ARG_NONE, &resume, 0, "Automatically resume aborted files" }, + {"recursive", 'R', POPT_ARG_NONE, &recursive, 0, "Recursively download files" }, + {"username", 'u', POPT_ARG_STRING, &username, 'u', "Username to use" }, + {"password", 'p', POPT_ARG_STRING, &password, 'p', "Password to use" }, + {"workgroup", 'w', POPT_ARG_STRING, &workgroup, 'w', "Workgroup to use (optional)" }, + {"nonprompt", 'n', POPT_ARG_NONE, &nonprompt, 'n', "Don't ask anything (non-interactive)" }, + {"debuglevel", 'd', POPT_ARG_INT, &debuglevel, 'd', "Debuglevel to use" }, + {"outputfile", 'o', POPT_ARG_STRING, &outputfile, 'o', "Write downloaded data to specified file" }, + {"dots", 'D', POPT_ARG_NONE, &dots, 'D', "Show dots as progress indication" }, + {"quiet", 'q', POPT_ARG_NONE, &quiet, 'q', "Be quiet" }, + {"verbose", 'v', POPT_ARG_NONE, &verbose, 'v', "Be verbose" }, + {"keep-permissions", 'P', POPT_ARG_NONE, &keep_permissions, 'P', "Keep permissions" }, + {"blocksize", 'b', POPT_ARG_INT, &blocksize, 'b', "Change number of bytes in a block"}, + {"rcfile", 'f', POPT_ARG_STRING, NULL, 0, "Use specified rc file"}, + POPT_AUTOHELP + POPT_TABLEEND + }; + poptContext pc; + + /* only read rcfile if it exists */ + asprintf(&rcfile, "%s/.smbgetrc", getenv("HOME")); + if(access(rcfile, F_OK) == 0) readrcfile(rcfile, long_options); + free(rcfile); + +#ifdef SIGWINCH + signal(SIGWINCH, change_columns); +#endif + signal(SIGINT, signal_quit); + signal(SIGTERM, signal_quit); + + pc = poptGetContext(argv[0], argc, argv, long_options, 0); + + while((c = poptGetNextOpt(pc)) >= 0) { + switch(c) { + case 'f': + readrcfile(poptGetOptArg(pc), long_options); + break; + case 'a': + username = ""; password = ""; + break; + } + } + + if(outputfile && recursive) { + fprintf(stderr, "The -o and -R options can not be used together.\n"); + return 1; + } + + if(smbc_init(get_auth_data, debuglevel) < 0) { + fprintf(stderr, "Unable to initialize libsmbclient\n"); + return 1; + } + + columns = get_num_cols(); + + total_start_time = time(NULL); + + while((file = poptGetArg(pc))) { + if(!recursive) return smb_download_file(file, "", recursive, resume, outputfile); + else return smb_download_dir(file, "", resume); + } + + clean_exit(); + + return 0; +} -- cgit From 14fa51cfe5cb723850e7fa29fbcb3db5a8762d46 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 13 Jan 2004 19:43:50 +0000 Subject: * allow dns lookups to be disabled for DOMAIN#1c (and #1b) names * fix some a mispelled variable name (This used to be commit 93fed3074f4384dc658cd0ec81ba2afbe8192417) --- source3/libsmb/namequery.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 83902971b0..dcbd11048e 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1036,6 +1036,11 @@ static BOOL internal_resolve_name(const char *name, int name_type, } /* set the name resolution order */ + + if ( strcmp( resolve_order, "NULL") == 0 ) { + DEBUG(8,("internal_resolve_name: all lookups disabled\n")); + return False; + } if ( !resolve_order ) pstrcpy(name_resolve_list, lp_name_resolve_order()); @@ -1252,9 +1257,23 @@ BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *c BOOL get_dc_list(const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only, int *ordered) { - /* defined the name resolve order to internal_name_resolve() - only used for looking up 0x1c names */ - const char *resolve_oder = (ads_only ? "ads" : lp_name_resolve_order()); + fstring resolve_order; + + /* if we are restricted to solely using DNS for looking + up a domain controller, make sure that host lookups + are enabled for the 'name resolve order'. If host lookups + are disabled and ads_only is True, then set the string to + NULL. */ + + fstrcpy( resolve_order, lp_name_resolve_order() ); + strlower_m( resolve_order ); + if ( ads_only ) { + if ( strstr( resolve_order, "host" ) ) + fstrcpy( resolve_order, "ads" ); + else + fstrcpy( resolve_order, "NULL" ); + } + *ordered = False; @@ -1275,7 +1294,7 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, if (!*pserver) - return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder); + return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); p = pserver; @@ -1288,7 +1307,7 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, while (next_token(&p,name,LIST_SEP,sizeof(name))) { if (strequal(name, "*")) { - if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_oder) ) + if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) ) num_addresses += auto_count; done_auto_lookup = True; DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); @@ -1301,7 +1320,7 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, just return the list of DC's */ if ( (num_addresses == 0) && !done_auto_lookup ) - return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder); + return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); /* maybe we just failed? */ @@ -1382,5 +1401,5 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, DEBUG(10,("get_dc_list: defaulting to internal auto lookup for domain %s\n", domain)); - return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder); + return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); } -- cgit From 0ad32d58f79a76d7f88558a8ecea5707168be518 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 14 Jan 2004 02:55:07 +0000 Subject: merge: fix XFS quotas the macro changed from HAVE_XFS_QUOTA -> HAVE_XFS_QUOTAS metze (This used to be commit ae20cf0810b9bef3d460994d5bf5e820c01296f0) --- source3/lib/sysquotas.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/lib/sysquotas.c b/source3/lib/sysquotas.c index 6883444e00..84ab3dd3d9 100644 --- a/source3/lib/sysquotas.c +++ b/source3/lib/sysquotas.c @@ -169,9 +169,9 @@ static struct { int (*get_quota)(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp); int (*set_quota)(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp); } sys_quota_backends[] = { -#ifdef HAVE_XFS_QUOTA +#ifdef HAVE_XFS_QUOTAS {"xfs", sys_get_xfs_quota, sys_set_xfs_quota}, -#endif /* HAVE_XFS_QUOTA */ +#endif /* HAVE_XFS_QUOTAS */ {NULL, NULL, NULL} }; -- cgit From 3a02e598fae7f6fd600f3e345aeee1a1a092f39f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 14 Jan 2004 06:41:46 +0000 Subject: Remove references to 'jn' which gcc-3.4 with precompiled headers doesn't like. Jeremy. (This used to be commit bf3d06a2e483d043c89a6b11ceb283a5b392859b) --- source3/msdfs/msdfs.c | 72 +++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index ce29c506bb..cd83756056 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -352,7 +352,7 @@ BOOL dfs_redirect(pstring pathname, connection_struct* conn, junction_map structure **********************************************************************/ -BOOL get_referred_path(char *pathname, struct junction_map* jn, +BOOL get_referred_path(char *pathname, struct junction_map* jucn, int* consumedcntp, BOOL* self_referralp) { struct dfs_path dp; @@ -365,7 +365,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, BOOL self_referral = False; - if (!pathname || !jn) + if (!pathname || !jucn) return False; if (self_referralp) @@ -385,13 +385,13 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, } } - pstrcpy(jn->service_name, dp.servicename); - pstrcpy(jn->volume_name, dp.reqpath); + pstrcpy(jucn->service_name, dp.servicename); + pstrcpy(jucn->volume_name, dp.reqpath); /* Verify the share is a dfs root */ - snum = lp_servicenumber(jn->service_name); + snum = lp_servicenumber(jucn->service_name); if(snum < 0) { - if ((snum = find_service(jn->service_name)) < 0) + if ((snum = find_service(jucn->service_name)) < 0) return False; } @@ -407,7 +407,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, if (*lp_msdfs_proxy(snum) != '\0') { struct referral* ref; - jn->referral_count = 1; + jucn->referral_count = 1; if ((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) { DEBUG(0, ("malloc failed for referral\n")); goto out; @@ -418,7 +418,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, pstrcat(ref->alternate_path, dp.reqpath); ref->proximity = 0; ref->ttl = REFERRAL_TTL; - jn->referral_list = ref; + jucn->referral_list = ref; if (consumedcntp) *consumedcntp = strlen(pathname); ret = True; @@ -427,7 +427,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, /* If not remote & not a self referral, return False */ if (!resolve_dfs_path(pathname, &dp, conn, False, - &jn->referral_list, &jn->referral_count, + &jucn->referral_list, &jucn->referral_count, self_referralp, consumedcntp)) { if (!*self_referralp) { DEBUG(3,("get_referred_path: No valid referrals for path %s\n", pathname)); @@ -438,7 +438,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, /* if self_referral, fill up the junction map */ if (*self_referralp) { struct referral* ref; - jn->referral_count = 1; + jucn->referral_count = 1; if((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) { DEBUG(0,("malloc failed for referral\n")); goto out; @@ -447,7 +447,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn, pstrcpy(ref->alternate_path,pathname); ref->proximity = 0; ref->ttl = REFERRAL_TTL; - jn->referral_list = ref; + jucn->referral_list = ref; if (consumedcntp) *consumedcntp = strlen(pathname); } @@ -712,7 +712,7 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref /********************************************************************** Creates a junction structure from a Dfs pathname **********************************************************************/ -BOOL create_junction(char* pathname, struct junction_map* jn) +BOOL create_junction(char* pathname, struct junction_map* jucn) { struct dfs_path dp; @@ -736,8 +736,8 @@ BOOL create_junction(char* pathname, struct junction_map* jn) return False; } - pstrcpy(jn->service_name,dp.servicename); - pstrcpy(jn->volume_name,dp.reqpath); + pstrcpy(jucn->service_name,dp.servicename); + pstrcpy(jucn->volume_name,dp.reqpath); return True; } @@ -745,22 +745,22 @@ BOOL create_junction(char* pathname, struct junction_map* jn) Forms a valid Unix pathname from the junction **********************************************************************/ -static BOOL junction_to_local_path(struct junction_map* jn, char* path, +static BOOL junction_to_local_path(struct junction_map* jucn, char* path, int max_pathlen, connection_struct *conn) { int snum; pstring conn_path; - if(!path || !jn) + if(!path || !jucn) return False; - snum = lp_servicenumber(jn->service_name); + snum = lp_servicenumber(jucn->service_name); if(snum < 0) return False; safe_strcpy(path, lp_pathname(snum), max_pathlen-1); safe_strcat(path, "/", max_pathlen-1); - safe_strcat(path, jn->volume_name, max_pathlen-1); + safe_strcat(path, jucn->volume_name, max_pathlen-1); pstrcpy(conn_path, lp_pathname(snum)); if (!create_conn_struct(conn, snum, conn_path)) @@ -769,7 +769,7 @@ static BOOL junction_to_local_path(struct junction_map* jn, char* path, return True; } -BOOL create_msdfs_link(struct junction_map* jn, BOOL exists) +BOOL create_msdfs_link(struct junction_map* jucn, BOOL exists) { pstring path; pstring msdfs_link; @@ -779,13 +779,13 @@ BOOL create_msdfs_link(struct junction_map* jn, BOOL exists) BOOL insert_comma = False; BOOL ret = False; - if(!junction_to_local_path(jn, path, sizeof(path), conn)) + if(!junction_to_local_path(jucn, path, sizeof(path), conn)) return False; /* form the msdfs_link contents */ pstrcpy(msdfs_link, "msdfs:"); - for(i=0; ireferral_count; i++) { - char* refpath = jn->referral_list[i].alternate_path; + for(i=0; ireferral_count; i++) { + char* refpath = jucn->referral_list[i].alternate_path; trim_char(refpath, '\\', '\\'); if(*refpath == '\0') { @@ -822,14 +822,14 @@ out: return ret; } -BOOL remove_msdfs_link(struct junction_map* jn) +BOOL remove_msdfs_link(struct junction_map* jucn) { pstring path; connection_struct conns; connection_struct *conn = &conns; BOOL ret = False; - if( junction_to_local_path(jn, path, sizeof(path), conn) ) { + if( junction_to_local_path(jucn, path, sizeof(path), conn) ) { if( SMB_VFS_UNLINK(conn, path) == 0 ) ret = True; @@ -839,7 +839,7 @@ BOOL remove_msdfs_link(struct junction_map* jn) return ret; } -static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count) +static BOOL form_junctions(int snum, struct junction_map* jucn, int* jn_count) { int cnt = *jn_count; DIR *dirp; @@ -867,13 +867,13 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count) DO NOT REMOVE THIS: NT clients will not work with us if this is not present */ - pstrcpy(jn[cnt].service_name, service_name); - jn[cnt].volume_name[0] = '\0'; - jn[cnt].referral_count = 1; + pstrcpy(jucn[cnt].service_name, service_name); + jucn[cnt].volume_name[0] = '\0'; + jucn[cnt].referral_count = 1; - ref = jn[cnt].referral_list + ref = jucn[cnt].referral_list = (struct referral*) malloc(sizeof(struct referral)); - if (jn[cnt].referral_list == NULL) { + if (jucn[cnt].referral_list == NULL) { DEBUG(0, ("Malloc failed!\n")); goto out; } @@ -897,10 +897,10 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count) goto out; while((dname = vfs_readdirname(conn, dirp)) != NULL) { - if (is_msdfs_link(conn, dname, &(jn[cnt].referral_list), - &(jn[cnt].referral_count), NULL)) { - pstrcpy(jn[cnt].service_name, service_name); - pstrcpy(jn[cnt].volume_name, dname); + if (is_msdfs_link(conn, dname, &(jucn[cnt].referral_list), + &(jucn[cnt].referral_count), NULL)) { + pstrcpy(jucn[cnt].service_name, service_name); + pstrcpy(jucn[cnt].volume_name, dname); cnt++; } } @@ -912,7 +912,7 @@ out: return ret; } -int enum_msdfs_links(struct junction_map* jn) +int enum_msdfs_links(struct junction_map* jucn) { int i=0; int jn_count = 0; @@ -922,7 +922,7 @@ int enum_msdfs_links(struct junction_map* jn) for(i=0;i < lp_numservices();i++) { if(lp_msdfs_root(i)) - form_junctions(i,jn,&jn_count); + form_junctions(i,jucn,&jn_count); } return jn_count; } -- cgit From 138c34e1506905ab97ca297c8cd697c1c8328276 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 14 Jan 2004 06:44:15 +0000 Subject: Remove duplicate extern. Jeremy. (This used to be commit 72d8eea25dbb54d7ef78264cd6f419220dc85fb6) --- source3/param/loadparm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index a1fb90157c..7afad4069b 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4296,7 +4296,6 @@ void get_private_directory(pstring privdir) void lp_set_logfile(const char *name) { - extern pstring debugf; string_set(&Globals.szLogFile, name); pstrcpy(debugf, name); } -- cgit From 84b24610e5940fcf9e4a2f1813790b131dc7fbe7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 14 Jan 2004 16:26:14 +0000 Subject: * Revert to using rpc for mixed mode AD domains. The reason for this are: (a) the set_dc_type_and_flags() cannot tell the different between connecting to an NT4 domain and an NT4 BDC of a mixed mode domain. (b) the connection management for the rpc backend only provides on named pipe per cli_state. So it is possible to connect to an NT4 BDC for netlogon and an AD mixed mode DC for lsarpc. RPC is the lowest common demonimator here. (c) Issue with the sequence number value between the highestCommittedUSN LDAP attribute and the seq_num returned via RPC. We will revisit this later, but the changes need to make this work right now are too broad and risky. (This used to be commit 86f24908c395cc832ae87b04c9da3d32449acad3) --- source3/nsswitch/winbindd_cache.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index 8dec89a6aa..91834e476f 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -112,9 +112,13 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain) break; } - /* if it have either of the indications of ADS, - use ads_methods */ - if ( domain->active_directory || domain->native_mode ) { + /* only use ADS for native modes at the momment. + The problem is the correct detection of mixed + mode domains from NT4 BDC's --jerry */ + + if ( domain->native_mode ) { + DEBUG(5,("get_cache: Setting ADS methods for domain %s\n", + domain->name)); domain->backend = &ads_methods; break; } @@ -123,6 +127,8 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain) } #endif default: + DEBUG(5,("get_cache: Setting MS-RPC methods for domain %s\n", + domain->name)); domain->backend = &msrpc_methods; } } -- cgit From 8f6fe5bce39378a059a374461f2a4fd32f4cd3b1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 14 Jan 2004 17:56:05 +0000 Subject: syncing abartlet's cracklib tests from 3.0 (This used to be commit 64c1db9bce27bbe5bc28acb631b265419d6d6286) --- source3/configure.in | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ source3/tests/crack.c | 7 +++++++ 2 files changed, 65 insertions(+) diff --git a/source3/configure.in b/source3/configure.in index 821ab3a1ea..07e4f3476f 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2966,6 +2966,64 @@ if test x"$samba_cv_HAVE_TRUNCATED_SALT" = x"yes"; then fi fi + +dictpath="/usr/lib/cracklib_dict" + +############################################### +# test for where we get FaciestCheck from +AC_MSG_CHECKING(where to use cracklib from (default=$dictpath)) +AC_ARG_WITH(cracklib, +[ --with-cracklib[=DIR] Look for cracklib dictionary in this location ], +[ case "$withval" in + yes) + AC_MSG_RESULT(${dictpath}) + ;; + no) + AC_MSG_RESULT(no) + dictpath="" + ;; + *) + dictpath="$withval" + AC_MSG_RESULT(${dictpath}) + ;; + esac ], + dictpath="" + AC_MSG_RESULT(no) +) + +if test x$dictpath != x""; then + AC_SEARCH_LIBS(FascistCheck, [crack], + [test "$ac_cv_search_crack" = "none required" || samba_cv_found_crack="yes" + AC_DEFINE(HAVE_CRACK,1,[Whether the system has the FaciestCheck function from cracklib])]) + + crack_saved_libs=$LIBS; + + if test x$samba_cv_found_crack=x"yes"; then + AC_SEARCH_LIBS(CRACKLIB_DICTPATH, [crypt], + AC_DEFINE(HAVE_CRACKLIB_DICTPATH, 1, [Whether we have given a CRACKLIB_DICTPATH in our headers]) + ) + + AC_DEFINE_UNQUOTED(SAMBA_CRACKLIB_DICTPATH, "$dictpath", [Where the cracklib dictionay is]) + AC_MSG_CHECKING(Whether we have a working cracklib) + AC_TRY_RUN([ + #include "${srcdir-.}/tests/crack.c"], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_WORKING_CRACKLIB,1,[Whether we have a working cracklib]) + AUTH_LIBS="-lcrack $AUTH_LIBS", + + AC_MSG_RESULT(no) + AC_MSG_WARN(cracklib exists - but does not function correctly), + + AC_MSG_RESULT(no) + AC_MSG_WARN(cannot test-run when cross-compiling) + ) + else + AC_MSG_CHECKING(Whether we have cracklib) + AC_MSG_RESULT(no) + fi + LIBS=$crack_saved_libs +fi + ######################################################################################## ## ## TESTS FOR SAM BACKENDS. KEEP THESE GROUPED TOGETHER diff --git a/source3/tests/crack.c b/source3/tests/crack.c index 1342887852..36119b3bbc 100644 --- a/source3/tests/crack.c +++ b/source3/tests/crack.c @@ -1,3 +1,10 @@ +#include + +#ifndef HAVE_CRACKLIB_DICTPATH +#ifndef CRACKLIB_DICTPATH +#define CRACKLIB_DICTPATH SAMBA_CRACKLIB_DICTPATH +#endif +#endif int main(int argc, char **argv) { FascistCheck("Foo", CRACKLIB_DICTPATH); -- cgit From fdac06716d063e14851a8d947a16362fbf521f73 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 14 Jan 2004 19:12:54 +0000 Subject: bug 660; using byte order safe macros (or tdb_unpack) when reading 2 or 4 byte values from a tdb buffer; also recognize smbjobs if the jobid < UNIX_JOB_START (This used to be commit ae6feb54a09a69e3a870b1a0d707b23eb8ca356a) --- source3/printing/printing.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index bdcd950450..ae7291bfc7 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -71,7 +71,7 @@ uint16 pjobid_to_rap(int snum, uint32 jobid) key.dsize = sizeof(jinfo); data = tdb_fetch(rap_tdb, key); if (data.dptr && data.dsize == sizeof(uint16)) { - memcpy(&rap_jobid, data.dptr, sizeof(uint16)); + rap_jobid = SVAL(data.dptr, 0); SAFE_FREE(data.dptr); DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n", (unsigned int)jobid, @@ -149,7 +149,7 @@ static void rap_jobid_delete(int snum, uint32 jobid) DEBUG(10,("rap_jobid_delete: deleting jobid %u\n", (unsigned int)jobid )); - memcpy(&rap_jobid, data.dptr, sizeof(uint16)); + rap_jobid = SVAL(data.dptr, 0); SAFE_FREE(data.dptr); data.dptr = (char *)&rap_jobid; data.dsize = sizeof(rap_jobid); @@ -615,7 +615,7 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid) pj.spooled = True; fstrcpy(pj.filename, old_pj ? old_pj->filename : ""); if (jobid < UNIX_JOB_START) { - pj.smbjob = (old_pj != NULL ? True : False); + pj.smbjob = True; fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document"); } else { pj.smbjob = False; @@ -648,7 +648,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void if ( key.dsize != sizeof(jobid) ) return 0; - memcpy(&jobid, key.dptr, sizeof(jobid)); + jobid = IVAL(key.dptr, 0); if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 ) return 0; free_nt_devicemode( &pjob.nt_devmode ); @@ -775,7 +775,7 @@ static pid_t get_updating_pid(fstring printer_name) return (pid_t)-1; } - memcpy(&updating_pid, data.dptr, sizeof(pid_t)); + updating_pid = IVAL(data.dptr, 0); SAFE_FREE(data.dptr); if (process_exists(updating_pid)) @@ -921,7 +921,7 @@ static void check_job_changed(int snum, TDB_DATA data, uint32 jobid) for (i = 0; i < job_count; i++) { uint32 ch_jobid; - memcpy(&ch_jobid, data.dptr + (i*4), 4); + ch_jobid = IVAL(data.dptr, i*4); if (ch_jobid == jobid) remove_from_jobs_changed(snum, jobid); } @@ -1407,7 +1407,7 @@ static BOOL remove_from_jobs_changed(int snum, uint32 jobid) for (i = 0; i < job_count; i++) { uint32 ch_jobid; - memcpy(&ch_jobid, data.dptr + (i*4), 4); + ch_jobid = IVAL(data.dptr, i*4); if (ch_jobid == jobid) { if (i < job_count -1 ) memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 ); @@ -1754,6 +1754,8 @@ static int get_queue_status(int snum, print_status_struct *status) data = tdb_fetch(pdb->tdb, key); if (data.dptr) { if (data.dsize == sizeof(print_status_struct)) + /* this memcpy is ok since the status struct was + not packed before storing it in the tdb */ memcpy(status, data.dptr, sizeof(print_status_struct)); SAFE_FREE(data.dptr); } @@ -2124,12 +2126,10 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun /* Get the stored queue data. */ data = tdb_fetch(pdb->tdb, key); - - if (data.dptr == NULL || data.dsize < 4) - qcount = 0; - else - memcpy(&qcount, data.dptr, 4); - + + if (data.dptr && data.dsize >= sizeof(qcount)) + len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount); + /* Get the changed jobs list. */ key.dptr = "INFO/jobs_changed"; key.dsize = strlen(key.dptr); @@ -2148,10 +2148,10 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun goto out; /* Retrieve the linearised queue data. */ - len = 0; + for( i = 0; i < qcount; i++) { uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime; - len += tdb_unpack(data.dptr + 4 + len, data.dsize - len, "ddddddff", + len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff", &qjob, &qsize, &qpage_count, @@ -2175,7 +2175,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun uint32 jobid; struct printjob *pjob; - memcpy(&jobid, &cgdata.dptr[i*4], 4); + jobid = IVAL(&cgdata.dptr, i*4); DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid)); pjob = print_job_find(snum, jobid); if (!pjob) { @@ -2260,6 +2260,8 @@ int print_queue_status(int snum, data = tdb_fetch(pdb->tdb, key); if (data.dptr) { if (data.dsize == sizeof(*status)) { + /* this memcpy is ok since the status struct was + not packed before storing it in the tdb */ memcpy(status, data.dptr, sizeof(*status)); } SAFE_FREE(data.dptr); -- cgit From 74aa29bd9ecf9bf74f04b36d8e0e0eb2080793d9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 14 Jan 2004 20:57:31 +0000 Subject: bug 770; correct fix this time; Make sure that we send the SMBjobid for unix jobs back to the client. Allows windows client to remove print jobs submitted from lpr (This used to be commit 6a7f9ebccd6a40455cb5446551f3d68ea9a7a824) --- source3/include/smb.h | 3 ++- source3/printing/printing.c | 26 +++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/source3/include/smb.h b/source3/include/smb.h index bef6bef691..ea39206f47 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -531,7 +531,8 @@ enum {LPQ_QUEUED=0,LPQ_PAUSED,LPQ_SPOOLING,LPQ_PRINTING,LPQ_ERROR,LPQ_DELETING, typedef struct _print_queue_struct { - int job; + int job; /* normally the SMB jobid -- see note in + printing.c:traverse_fn_delete() */ int size; int page_count; int status; diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ae7291bfc7..1f0bb1e074 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -597,7 +597,7 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid) { struct printjob pj, *old_pj; - if (jobid == (uint32)-1) + if (jobid == (uint32)-1) jobid = q->job + UNIX_JOB_START; /* Preserve the timestamp on an existing unix print job */ @@ -671,9 +671,11 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n", (unsigned int)jobid )); pjob_delete(ts->snum, jobid); - } else - ts->total_jobs++; - return 0; + return 0; + } + + /* need to continue the the bottom of the function to + save the correct attributes */ } /* maybe it hasn't been spooled yet */ @@ -690,10 +692,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void return 0; } - for (i=0;iqcount;i++) { - uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file); - if (jobid == curr_jobid) - break; + /* this check only makes sense for jobs submitted from Windows clients */ + + if ( pjob.smbjob ) { + for (i=0;iqcount;i++) { + uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file); + if (jobid == curr_jobid) + break; + } } /* The job isn't in the system queue - we have to assume it has @@ -720,7 +726,9 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void } /* Save the pjob attributes we will store. */ - ts->queue[i].job = jobid; + /* FIXME!!! This is the only place where queue->job + represents the SMB jobid --jerry */ + ts->queue[i].job = jobid; ts->queue[i].size = pjob.size; ts->queue[i].page_count = pjob.page_count; ts->queue[i].status = pjob.status; -- cgit From 77201a85d811d55812018a5752272e6d042a6b0b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 14 Jan 2004 21:22:44 +0000 Subject: Fix initgroups() call nss_winbind on solaris; patch from John Klinger (This used to be commit c4d58ec5d5c2b8947824d78639a7e9e615e2a400) --- source3/nsswitch/winbind_nss_solaris.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source3/nsswitch/winbind_nss_solaris.c b/source3/nsswitch/winbind_nss_solaris.c index 6671090e6a..8f03eb4cd6 100644 --- a/source3/nsswitch/winbind_nss_solaris.c +++ b/source3/nsswitch/winbind_nss_solaris.c @@ -256,7 +256,23 @@ _nss_winbind_getgrgid_solwrap(nss_backend_t* be, void* args) static NSS_STATUS _nss_winbind_getgroupsbymember_solwrap(nss_backend_t* be, void* args) { + int errnop; + struct nss_groupsbymem *gmem = (struct nss_groupsbymem *)args; + NSS_DEBUG("_nss_winbind_getgroupsbymember"); + + _nss_winbind_initgroups_dyn(gmem->username, + gmem->gid_array[0], /* Primary Group */ + &gmem->numgids, + &gmem->maxgids, + &gmem->gid_array, + gmem->maxgids, + &errnop); + + /* + * Always return NOTFOUND so nsswitch will get info from all + * the database backends specified in the nsswitch.conf file. + */ return NSS_STATUS_NOTFOUND; } -- cgit From 24a3c24383303b6b51890ee8ab990a25a4500a23 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 14 Jan 2004 21:46:29 +0000 Subject: Trust passwords types for use with SAM_TRUST_PASSWD structure. rafal (This used to be commit ea15c148fd6393512f2fd95d88db6546d40cf14c) --- source3/include/secrets.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source3/include/secrets.h b/source3/include/secrets.h index cb4fbd043a..8c39394058 100644 --- a/source3/include/secrets.h +++ b/source3/include/secrets.h @@ -49,6 +49,13 @@ #define SECRETS_AUTH_DOMAIN "SECRETS/AUTH_DOMAIN" #define SECRETS_AUTH_PASSWORD "SECRETS/AUTH_PASSWORD" +/* Trust password type flags */ +#define PASS_MACHINE_TRUST_NT 0x0001 +#define PASS_SERVER_TRUST_NT 0x0002 +#define PASS_DOMAIN_TRUST_NT 0x0004 +#define PASS_MACHINE_TRUST_ADS 0x0008 +#define PASS_DOMAIN_TRUST_ADS 0x0010 + /* structure for storing machine account password (ie. when samba server is member of a domain */ struct machine_acct_pass { -- cgit From f0145a2a75fe19dadd019ffc76b2251855e450d7 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 14 Jan 2004 21:50:25 +0000 Subject: Comment and formatting fix. rafal (This used to be commit 336720416abd1f6d62f9a6748ae6a0454976c9d4) --- source3/passdb/secrets.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index f9557cac42..b389e42b7f 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -238,7 +238,7 @@ uint32 get_default_sec_channel(void) /************************************************************************ Routine to get the trust account password for a domain. The user of this function must have locked the trust password file using - the above call. + the above secrets_lock_trust_account_password(). ************************************************************************/ BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16], @@ -562,7 +562,8 @@ BOOL secrets_store_ldap_pw(const char* dn, char* pw) * @return nt status code of rpc response **/ -NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned int max_num_domains, int *num_domains, TRUSTDOM ***domains) +NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned int max_num_domains, + int *num_domains, TRUSTDOM ***domains) { TDB_LIST_NODE *keys, *k; TRUSTDOM *dom = NULL; -- cgit From 742fbfcaba5c0ffe53ece547982b361f7c9d7b8a Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Wed, 14 Jan 2004 22:02:16 +0000 Subject: Initial design of some of the functions to operate on trust passwords from passdb backend level (tdbsam, in this case). It is written as wrapper for secrets_ calls that use secrets.tdb file and is not treated as eventual solution. Trust passwords are being handled uniformly, SAM_TRUST_PASSWD structure, and so they should be stored as well. Note, this code is disabled ie. not used anywhere yet. I'm working on next routines in line. rafal (This used to be commit 02ac9332ab1d34f47667b40ce23b2b5d04c4dff1) --- source3/passdb/pdb_tdb.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 966682563c..1d8fb9b7ec 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -643,6 +643,203 @@ static void free_private_data(void **vp) /* No need to free any further, as it is talloc()ed */ } +/** + * Start enumerating through trust passwords (machine and + * interdomain nt/ads) + * + * @param methods methods belonging in pdb context (module) + * @param trust trust password structure + * + * @return nt status of performed operation + **/ + +static NTSTATUS tdbsam_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct trust_passwd_data t; + TALLOC_CTX *mem_ctx; + + TRUSTDOM **trustdom; + static int enum_ctx; + int num_domains = 0; + unsigned int max_domains = 1; + char *dom_name, *dom_pass; + + smb_ucs2_t *uni_dom_name; + uint8 mach_pass[16]; + uint32 sec_chan; + + if (!methods) return NT_STATUS_UNSUCCESSFUL; + + /* + * NT domain trust passwords + */ + + /* rewind enumeration when passed NULL pointer as a trust */ + if (!trust) { + enum_ctx = 0; + return NT_STATUS_OK; + } + + mem_ctx = talloc_init("tdbsam_gettrustpwent: trust password enumeration"); + + /* fetch next trusted domain (one at a time) and its full information */ + nt_status = secrets_get_trusted_domains(mem_ctx, &enum_ctx, max_domains, &num_domains, + &trustdom); + if (num_domains) { + pull_ucs2_talloc(mem_ctx, &dom_name, trustdom[0]->name); + if (secrets_fetch_trusted_domain_password(dom_name, &dom_pass, &t.domain_sid, + &t.mod_time)) { + + t.uni_name_len = strnlen_w(trustdom[0]->name, 32); + strncpy_w(t.uni_name, trustdom[0]->name, t.uni_name_len); + safe_strcpy(t.pass, dom_pass, FSTRING_LEN - 1); + t.flags = PASS_DOMAIN_TRUST_NT; + + SAFE_FREE(dom_pass); + talloc_destroy(mem_ctx); + trust->private = t; + return nt_status; + } else { + talloc_destroy(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + } + + /* + * NT machine trust password + */ + + if (secrets_lock_trust_account_password(lp_workgroup(), True)) { + sec_chan = get_default_sec_channel(); + if (secrets_fetch_trust_account_password(lp_workgroup(), mach_pass, &t.mod_time, + &sec_chan)) { + + t.uni_name_len = strlen(lp_workgroup()); + push_ucs2_talloc(mem_ctx, &uni_dom_name, lp_workgroup()); + strncpy_w(t.uni_name, uni_dom_name, t.uni_name_len); + safe_strcpy(t.pass, mach_pass, FSTRING_LEN - 1); + t.flags = PASS_MACHINE_TRUST_NT; + if (!secrets_fetch_domain_sid(lp_workgroup(), &t.domain_sid)) { + talloc_destroy(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + talloc_destroy(mem_ctx); + trust->private = t; + return NT_STATUS_OK; + } + secrets_lock_trust_account_password(lp_workgroup(), False); + } else { + talloc_destroy(mem_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + /* + * ADS machine trust password (TODO) + */ + + talloc_destroy(mem_ctx); + return nt_status; +} + +/** + * Get trust password by trusted party sid + * + * @param methods methods belonging to pdb context (module) + * @param trust trust password structure + * @param sid trusted party sid + * + * @return nt status of performed operation + **/ + +static NTSTATUS tdbsam_gettrustpwsid(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, + const DOM_SID *sid) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + return nt_status; +} + + +/** + * Add new trust password. + * + * @param methods methods belonging in pdb context (module) + * @param trust trust password structure + * + * @return nt status of performed operation + **/ + +static NTSTATUS tdbsam_add_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD *trust) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + BOOL status = False; + TALLOC_CTX *mem_ctx; + + char* domain = NULL; + struct trust_passwd_data t = trust->private; + uint32 sec_chan; + + mem_ctx = talloc_init("tdbsam_add_trust_passwd: storing new trust password"); + + /* convert unicode name to char* (used to form the key) */ + pull_ucs2_talloc(mem_ctx, &domain, t.uni_name); + + /* add nt machine trust password */ + if (t.flags & (PASS_MACHINE_TRUST_NT | PASS_SERVER_TRUST_NT)) { + sec_chan = (t.flags & PASS_MACHINE_TRUST_NT) ? SEC_CHAN_WKSTA : SEC_CHAN_BDC; + status = secrets_store_machine_password(t.pass, domain, sec_chan); + if (status) + status = secrets_store_domain_sid(domain, &t.domain_sid); + + nt_status = status ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + + /* add nt domain trust password */ + } else if (t.flags & PASS_DOMAIN_TRUST_NT) { + status = secrets_store_trusted_domain_password(domain, t.uni_name, t.uni_name_len, + t.pass, t.domain_sid); + nt_status = status ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + + /* add ads machine trust password (TODO) */ + } else if (t.flags & PASS_MACHINE_TRUST_ADS) { + } + + talloc_destroy(mem_ctx); + return nt_status; +} + + +/** + * Update trust password. + * + * @param methods methods belonging in pdb context (module) + * @param trust trust password structure + * + * @return nt status of performed operation + **/ + +static NTSTATUS tdbsam_update_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust) +{ + NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED; + return nt_status; +} + + +/** + * Delete trust password. + * + * @param methods methods belonging in pdb context (module) + * @param trust trust password structure + * + * @return nt status of performed operation + **/ + +static NTSTATUS tdbsam_delete_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust) +{ + NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED; + return nt_status; +} + static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { @@ -663,6 +860,11 @@ static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_meth (*pdb_method)->add_sam_account = tdbsam_add_sam_account; (*pdb_method)->update_sam_account = tdbsam_update_sam_account; (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account; + (*pdb_method)->gettrustpwent = tdbsam_gettrustpwent; + (*pdb_method)->gettrustpwsid = tdbsam_gettrustpwsid; + (*pdb_method)->add_trust_passwd = tdbsam_add_trust_passwd; + (*pdb_method)->update_trust_passwd = tdbsam_update_trust_passwd; + (*pdb_method)->delete_trust_passwd = tdbsam_delete_trust_passwd; tdb_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct tdbsam_privates)); -- cgit From a68e3446d0140be9f1b0b538986ee2c6a7c7c2cc Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 14 Jan 2004 23:00:06 +0000 Subject: source/rpc_parse/parse_prs.c ZERO_STRUCTP(ps) not needed as it is done in prs_init now testsuite/printing/psec.c cannot do a prs_mem_free() when tdb_prs_fetch fails as the prs structure has not been initialized (This used to be commit 6289d7b842819fb31bec93119f15b3823e02b49e) --- source3/rpc_parse/parse_prs.c | 1 - testsuite/printing/psec.c | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 58652fa0c5..0e5a25fe8c 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -1307,7 +1307,6 @@ int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *me if (!dbuf.dptr) return -1; - ZERO_STRUCTP(ps); prs_init(ps, 0, mem_ctx, UNMARSHALL); prs_give_memory(ps, dbuf.dptr, dbuf.dsize, True); diff --git a/testsuite/printing/psec.c b/testsuite/printing/psec.c index 9d38b9b10a..7ba40b18a3 100644 --- a/testsuite/printing/psec.c +++ b/testsuite/printing/psec.c @@ -195,8 +195,11 @@ int psec_getsec(char *printer) if (tdb_prs_fetch(tdb, keystr, &ps, mem_ctx) != 0) { printf("error fetching descriptor for printer %s\n", printer); - result = 1; - goto done; + /* cannot do a prs_mem_free() when tdb_prs_fetch fails */ + /* as the prs structure has not been initialized */ + tdb_close(tdb); + talloc_destroy(mem_ctx); + return 1; } /* Unpack into security descriptor buffer */ -- cgit From 50854a1603d0921a0884e817c44b48309f2812f5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Jan 2004 05:17:40 +0000 Subject: BUG 972; check pointer in cli_ds_getprimarydominfo() before trying to copy a structure (This used to be commit a1aed0b517f7476301d8fe4dfebac3db178ba1cd) --- source3/rpc_client/cli_ds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_client/cli_ds.c b/source3/rpc_client/cli_ds.c index 8c2821d5af..09e63a4714 100644 --- a/source3/rpc_client/cli_ds.c +++ b/source3/rpc_client/cli_ds.c @@ -62,7 +62,7 @@ NTSTATUS cli_ds_getprimarydominfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (ctr) { + if ( r.ptr && ctr ) { ctr->basic = talloc(mem_ctx, sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC)); if (!ctr->basic) goto done; -- cgit From 353aab1ea1471768db7eb8b9799086176d7f83b5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Jan 2004 06:56:00 +0000 Subject: BUG 936: fix bind credentials for schannel binds in smbd (and add a comment to winbindd_cm about this (This used to be commit c1174cf57b1b6fad03de23f6a4ff952671dc87d7) --- source3/auth/auth_domain.c | 13 +++++++++---- source3/nsswitch/winbindd_cm.c | 6 +++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 0bf2031a37..73e0ae7949 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -41,7 +41,8 @@ extern BOOL global_machine_password_needs_changing; **/ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, - const char *dc_name, struct in_addr dc_ip, + const char *domain, const char *dc_name, + struct in_addr dc_ip, const char *setup_creds_as, uint16 sec_chan, const unsigned char *trust_passwd, @@ -111,6 +112,10 @@ machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli))); return NT_STATUS_NO_MEMORY; } + /* This must be the remote domain (not ours) for schannel */ + + fstrcpy( (*cli)->domain, domain ); + result = cli_nt_establish_netlogon(*cli, sec_chan, trust_passwd); if (!NT_STATUS_IS_OK(result)) { @@ -162,8 +167,8 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, /* rety loop for robustness */ for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++) { - nt_status = connect_to_domain_password_server(&cli, dc_name, dc_ip, setup_creds_as, - sec_chan, trust_passwd, &retry); + nt_status = connect_to_domain_password_server(&cli, domain, dc_name, + dc_ip, setup_creds_as, sec_chan, trust_passwd, &retry); } if ( !NT_STATUS_IS_OK(nt_status) ) { @@ -297,7 +302,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, /* we need our DC to send the net_sam_logon() request to */ if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) { - DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n", + DEBUG(5,("check_ntdomain_security: unable to locate a DC for domain %s\n", user_info->domain.str)); return NT_STATUS_NO_LOGON_SERVERS; } diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 44fc06fe54..29b856ec45 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -509,7 +509,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain ) done: - /* close the connection; no other cals use this pipe and it is called only + /* close the connection; no other calls use this pipe and it is called only on reestablishing the domain list --jerry */ if ( conn.cli ) @@ -686,9 +686,9 @@ NTSTATUS cm_get_netlogon_cli(struct winbindd_domain *domain, if ( sec_channel_type == SEC_CHAN_DOMAIN ) fstr_sprintf(conn->cli->mach_acct, "%s$", lp_workgroup()); - + /* This must be the remote domain (not ours) for schannel */ + fstrcpy( conn->cli->domain, domain->name); - result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd); -- cgit From 913d1745ca902326ec39a9e8ae9e1f133fee5060 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 15 Jan 2004 07:19:12 +0000 Subject: Merge of POBAD_CC removal from 3.0 (This used to be commit 835a28337f97da143d5b9201a5080fde06bbedf1) --- examples/VFS/configure.in | 3 --- source3/Makefile.in | 3 --- source3/configure.in | 3 --- 3 files changed, 9 deletions(-) diff --git a/examples/VFS/configure.in b/examples/VFS/configure.in index a0d1dc9630..3799e3a507 100644 --- a/examples/VFS/configure.in +++ b/examples/VFS/configure.in @@ -55,7 +55,6 @@ AC_SUBST(SHLD) AC_SUBST(HOST_OS) AC_SUBST(PICFLAG) AC_SUBST(PICSUFFIX) -AC_SUBST(POBAD_CC) AC_SUBST(SHLIBEXT) AC_SUBST(INSTALLCLIENTCMD_SH) AC_SUBST(INSTALLCLIENTCMD_A) @@ -181,7 +180,6 @@ SONAMEFLAG="#" SHLD="\${CC}" PICFLAG="" PICSUFFIX="po" -POBAD_CC="#" SHLIBEXT="so" if test "$enable_shared" = "yes"; then @@ -214,7 +212,6 @@ if test "$enable_shared" = "yes"; then ## ${CFLAGS} added for building 64-bit shared ## libs using Sun's Compiler LDSHFLAGS="-G \${CFLAGS}" - POBAD_CC="" PICSUFFIX="po.o" fi ;; diff --git a/source3/Makefile.in b/source3/Makefile.in index 68aead0fc2..1bd3392f02 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -754,7 +754,6 @@ dynconfig.@PICSUFFIX@: dynconfig.c Makefile @echo Compiling $*.c with @PICFLAGS@ @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c $< -o $*.@PICSUFFIX@ @BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@ -@POBAD_CC@ -@mv $*.@PICSUFFIX@.o $@ lib/version.o: lib/version.c include/version.h @echo Compiling $*.c @@ -766,7 +765,6 @@ lib/version.@PICSUFFIX@: lib/version.c include/version.h @echo Compiling $*.c with @PICFLAGS@ @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c $< -o $*.@PICSUFFIX@ @BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@ -@POBAD_CC@ @mv $*.@PICSUFFIX@.o $@ smbd/build_options.o: smbd/build_options.c Makefile include/config.h include/build_env.h include/proto.h @echo Compiling $*.c @@ -782,7 +780,6 @@ smbd/build_options.c: include/config.h.in script/mkbuildoptions.awk @echo Compiling $*.c with @PICFLAGS@ @$(CC) -I. -I$(srcdir) $(FLAGS) @PICFLAGS@ -c $< -o $*.@PICSUFFIX@ @BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@ -@POBAD_CC@ @mv $*.@PICSUFFIX@.o $@ bin/.dummy: @if (: >> $@ || : > $@) >/dev/null 2>&1; then :; else \ diff --git a/source3/configure.in b/source3/configure.in index 07e4f3476f..cf695eb05c 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -163,7 +163,6 @@ AC_SUBST(SHLD) AC_SUBST(HOST_OS) AC_SUBST(PICFLAGS) AC_SUBST(PICSUFFIX) -AC_SUBST(POBAD_CC) AC_SUBST(SHLIBEXT) AC_SUBST(INSTALLCLIENT) AC_SUBST(INSTALLCLIENTCMD_SH) @@ -1063,7 +1062,6 @@ SONAMEFLAG="#" SHLD="\${CC} \${CFLAGS}" PICFLAGS="" PICSUFFIX="po" -POBAD_CC="#" SHLIBEXT="so" if test "$enable_shared" = "yes"; then @@ -1097,7 +1095,6 @@ if test "$enable_shared" = "yes"; then ## ${CFLAGS} added for building 64-bit shared ## libs using Sun's Compiler LDSHFLAGS="-G \${CFLAGS}" - POBAD_CC="" PICSUFFIX="po.o" fi AC_DEFINE(STAT_ST_BLOCKSIZE,512,[The size of a block]) -- cgit From 4e8aec8ca8481cf2102ac3052c4ee1ff37ec2f7c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Jan 2004 08:56:08 +0000 Subject: merge: * Fix XFS quotas: XFS_USER_QUOTA -> USRQUOTA XFS_GROUP_QUOTA -> GRPQUOTA * Fix disk_free calculation with group quotas. * Add debug class 'quota' and a lot of DEBUG()'s to the quota code. metze (This used to be commit 33c6ca3b4bc0898893b5d95ea2485b7694b9d198) --- source3/include/debug.h | 1 + source3/lib/debug.c | 1 + source3/lib/sysquotas.c | 39 +++++++++++++++++----- source3/lib/sysquotas_4A.c | 37 ++++++++++++++++----- source3/lib/sysquotas_linux.c | 75 +++++++++++++++++++++++++++++++++++++++++++ source3/lib/sysquotas_xfs.c | 63 +++++++++++++++++++++++++----------- source3/smbd/ntquotas.c | 3 ++ source3/smbd/quotas.c | 17 +++++----- 8 files changed, 194 insertions(+), 42 deletions(-) diff --git a/source3/include/debug.h b/source3/include/debug.h index 70f9f7706d..d47f69db65 100644 --- a/source3/include/debug.h +++ b/source3/include/debug.h @@ -89,6 +89,7 @@ extern int DEBUGLEVEL; #define DBGC_WINBIND 11 #define DBGC_VFS 12 #define DBGC_IDMAP 13 +#define DBGC_QUOTA 14 /* So you can define DBGC_CLASS before including debug.h */ #ifndef DBGC_CLASS diff --git a/source3/lib/debug.c b/source3/lib/debug.c index fdbd54fafb..0050761e9a 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -155,6 +155,7 @@ static const char *default_classname_table[] = { "winbind", /* DBGC_WINBIND */ "vfs", /* DBGC_VFS */ "idmap", /* DBGC_IDMAP */ + "quota", /* DBGC_QUOTA */ NULL }; diff --git a/source3/lib/sysquotas.c b/source3/lib/sysquotas.c index 84ab3dd3d9..1c5c7e8bd4 100644 --- a/source3/lib/sysquotas.c +++ b/source3/lib/sysquotas.c @@ -21,6 +21,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_QUOTA + #ifdef HAVE_SYS_QUOTAS #if defined(HAVE_QUOTACTL_4A) @@ -384,12 +387,18 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI return ret; } + errno = 0; + DEBUG(10,("sys_get_quota() uid(%u, %u)\n", (unsigned)getuid(), (unsigned)geteuid())); + for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].get_quota);i++) { if (strcmp(fs,sys_quota_backends[i].name)==0) { ret = sys_quota_backends[i].get_quota(mntpath, bdev, qtype, id, dp); if (ret!=0) { - DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", - fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + DEBUG(3,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s.\n", + fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno))); + } else { + DEBUG(10,("sys_get_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n", + fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid))); } ready = True; break; @@ -400,8 +409,11 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI /* use the default vfs quota functions */ ret=sys_get_vfs_quota(mntpath, bdev, qtype, id, dp); if (ret!=0) { - DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", - "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + DEBUG(3,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s\n", + "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno))); + } else { + DEBUG(10,("sys_get_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n", + "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid))); } } @@ -410,6 +422,7 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI SAFE_FREE(fs); if ((ret!=0)&& (errno == EDQUOT)) { + DEBUG(10,("sys_get_quota() warning over quota!\n")); return 0; } @@ -441,12 +454,18 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI return ret; } + errno = 0; + DEBUG(10,("sys_set_quota() uid(%u, %u)\n", (unsigned)getuid(), (unsigned)geteuid())); + for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].set_quota);i++) { if (strcmp(fs,sys_quota_backends[i].name)==0) { ret = sys_quota_backends[i].set_quota(mntpath, bdev, qtype, id, dp); if (ret!=0) { - DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", - fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + DEBUG(3,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s.\n", + fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno))); + } else { + DEBUG(10,("sys_set_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n", + fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid))); } ready = True; break; @@ -457,8 +476,11 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI /* use the default vfs quota functions */ ret=sys_set_vfs_quota(mntpath, bdev, qtype, id, dp); if (ret!=0) { - DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", - "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + DEBUG(3,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d]: %s.\n", + "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),strerror(errno))); + } else { + DEBUG(10,("sys_set_%s_quota() called for mntpath[%s] bdev[%s] qtype[%d] id[%d].\n", + "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid))); } } @@ -467,6 +489,7 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI SAFE_FREE(fs); if ((ret!=0)&& (errno == EDQUOT)) { + DEBUG(10,("sys_set_quota() warning over quota!\n")); return 0; } diff --git a/source3/lib/sysquotas_4A.c b/source3/lib/sysquotas_4A.c index 66b367f099..ffb4123799 100644 --- a/source3/lib/sysquotas_4A.c +++ b/source3/lib/sysquotas_4A.c @@ -21,6 +21,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_QUOTA + #ifdef HAVE_QUOTACTL_4A /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */ /* this is used by: HPUX,IRIX */ @@ -89,6 +92,9 @@ int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt switch (qtype) { case SMB_USER_QUOTA_TYPE: + DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))&&errno != EDQUOT) { return ret; } @@ -103,6 +109,9 @@ int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt break; #ifdef HAVE_GROUP_QUOTA case SMB_GROUP_QUOTA_TYPE: + DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))&&errno != EDQUOT) { return ret; } @@ -119,6 +128,9 @@ int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt case SMB_USER_FS_QUOTA_TYPE: id.uid = getuid(); + DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))==0) { qflags |= QUOTAS_DENY_DISK; } @@ -129,6 +141,9 @@ int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt case SMB_GROUP_FS_QUOTA_TYPE: id.gid = getgid(); + DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))==0) { qflags |= QUOTAS_DENY_DISK; } @@ -184,10 +199,16 @@ int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt switch (qtype) { case SMB_USER_QUOTA_TYPE: + DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", + path, bdev, (unsigned)id.uid)); + ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (void *)&D); break; #ifdef HAVE_GROUP_QUOTA case SMB_GROUP_QUOTA_TYPE: + DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", + path, bdev, (unsigned)id.gid)); + ret = quotactl(QCMD(Q_SETQLIM,GRPQUOTA), bdev, id.gid, (void *)&D); break; #endif /* HAVE_GROUP_QUOTA */ @@ -202,9 +223,11 @@ int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt * we need to fix sys_path_to_bdev() * */ -#if 0 id.uid = getuid(); + DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", + path, bdev, (unsigned)id.uid)); +#if 0 ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D); if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) { @@ -231,11 +254,9 @@ int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt } } - DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", + DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", ret,errno,strerror(errno),id.uid,bdev)); #else - id.uid = getuid(); - if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))==0) { oldqflags |= QUOTAS_DENY_DISK; } @@ -259,9 +280,11 @@ int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt * we need to fix sys_path_to_bdev() * */ -#if 0 id.gid = getgid(); + DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", + path, bdev, (unsigned)id.gid)); +#if 0 ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (void *)&D); if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) { @@ -288,11 +311,9 @@ int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt } } - DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", + DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", ret,errno,strerror(errno),id.gid,bdev)); #else - id.gid = getgid(); - if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))==0) { oldqflags |= QUOTAS_DENY_DISK; } diff --git a/source3/lib/sysquotas_linux.c b/source3/lib/sysquotas_linux.c index be42fa23f4..3867c1b0f9 100644 --- a/source3/lib/sysquotas_linux.c +++ b/source3/lib/sysquotas_linux.c @@ -21,6 +21,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_QUOTA + #ifdef HAVE_QUOTACTL_LINUX #include "samba_linux_quota.h" @@ -39,24 +42,36 @@ static int sys_get_linux_v1_quota(const char *path, const char *bdev, enum SMB_Q switch (qtype) { case SMB_USER_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) { return ret; } break; case SMB_GROUP_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) { return ret; } break; case SMB_USER_FS_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { qflags |= QUOTAS_DENY_DISK; } break; case SMB_GROUP_FS_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { qflags |= QUOTAS_DENY_DISK; } @@ -110,18 +125,30 @@ static int sys_set_linux_v1_quota(const char *path, const char *bdev, enum SMB_Q switch (qtype) { case SMB_USER_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", + path, bdev, (unsigned)id.uid)); + ret = quotactl(QCMD(Q_V1_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D); break; case SMB_GROUP_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", + path, bdev, (unsigned)id.gid)); + ret = quotactl(QCMD(Q_V1_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D); break; case SMB_USER_FS_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { oldqflags |= QUOTAS_DENY_DISK; } break; case SMB_GROUP_FS_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { oldqflags |= QUOTAS_DENY_DISK; } @@ -149,24 +176,36 @@ static int sys_get_linux_v2_quota(const char *path, const char *bdev, enum SMB_Q switch (qtype) { case SMB_USER_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) { return ret; } break; case SMB_GROUP_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) { return ret; } break; case SMB_USER_FS_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { qflags |= QUOTAS_DENY_DISK; } break; case SMB_GROUP_FS_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { qflags |= QUOTAS_DENY_DISK; } @@ -220,18 +259,30 @@ static int sys_set_linux_v2_quota(const char *path, const char *bdev, enum SMB_Q switch (qtype) { case SMB_USER_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", + path, bdev, (unsigned)id.uid)); + ret = quotactl(QCMD(Q_V2_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D); break; case SMB_GROUP_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", + path, bdev, (unsigned)id.gid)); + ret = quotactl(QCMD(Q_V2_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D); break; case SMB_USER_FS_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { oldqflags |= QUOTAS_DENY_DISK; } break; case SMB_GROUP_FS_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { oldqflags |= QUOTAS_DENY_DISK; } @@ -259,24 +310,36 @@ static int sys_get_linux_gen_quota(const char *path, const char *bdev, enum SMB_ switch (qtype) { case SMB_USER_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) { return ret; } break; case SMB_GROUP_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) { return ret; } break; case SMB_USER_FS_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { qflags |= QUOTAS_DENY_DISK; } break; case SMB_GROUP_FS_QUOTA_TYPE: + DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { qflags |= QUOTAS_DENY_DISK; } @@ -330,18 +393,30 @@ static int sys_set_linux_gen_quota(const char *path, const char *bdev, enum SMB_ switch (qtype) { case SMB_USER_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", + path, bdev, (unsigned)id.uid)); + ret = quotactl(QCMD(Q_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D); break; case SMB_GROUP_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", + path, bdev, (unsigned)id.gid)); + ret = quotactl(QCMD(Q_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D); break; case SMB_USER_FS_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", + path, bdev, (unsigned)id.uid)); + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { oldqflags |= QUOTAS_DENY_DISK; } break; case SMB_GROUP_FS_QUOTA_TYPE: + DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", + path, bdev, (unsigned)id.gid)); + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { oldqflags |= QUOTAS_DENY_DISK; } diff --git a/source3/lib/sysquotas_xfs.c b/source3/lib/sysquotas_xfs.c index 6d7d9f9e6a..9fe4ec0d99 100644 --- a/source3/lib/sysquotas_xfs.c +++ b/source3/lib/sysquotas_xfs.c @@ -21,6 +21,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_QUOTA + #ifndef HAVE_SYS_QUOTAS #ifdef HAVE_XFS_QUOTAS #undef HAVE_XFS_QUOTAS @@ -86,17 +89,26 @@ int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt switch (qtype) { case SMB_USER_QUOTA_TYPE: - if ((ret=quotactl(QCMD(Q_XGETQUOTA,XFS_USER_QUOTA), bdev, id.uid, (caddr_t)&D))) + DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", + path, bdev, (unsigned)id.uid)); + + if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))) return ret; break; #ifdef HAVE_GROUP_QUOTA case SMB_GROUP_QUOTA_TYPE: - if ((ret=quotactl(QCMD(Q_XGETQUOTA,XFS_GROUP_QUOTA), bdev, id.gid, (caddr_t)&D))) + DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", + path, bdev, (unsigned)id.gid)); + + if ((ret=quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))) return ret; break; #endif /* HAVE_GROUP_QUOTA */ - case SMB_USER_FS_QUOTA_TYPE: - quotactl(QCMD(Q_XGETQSTAT,XFS_USER_QUOTA), bdev, -1, (caddr_t)&F); + case SMB_USER_FS_QUOTA_TYPE: + DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", + path, bdev, (unsigned)id.uid)); + + quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F); if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) { qflags |= QUOTAS_DENY_DISK; @@ -109,8 +121,11 @@ int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt break; #ifdef HAVE_GROUP_QUOTA - case SMB_GROUP_FS_QUOTA_TYPE: - quotactl(QCMD(Q_XGETQSTAT,XFS_GROUP_QUOTA), bdev, -1, (caddr_t)&F); + case SMB_GROUP_FS_QUOTA_TYPE: + DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", + path, bdev, (unsigned)id.gid)); + + quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F); if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) { qflags |= QUOTAS_DENY_DISK; @@ -174,17 +189,26 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt switch (qtype) { case SMB_USER_QUOTA_TYPE: + DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", + path, bdev, (unsigned)id.uid)); + D.d_fieldmask |= FS_DQ_LIMIT_MASK; - ret = quotactl(QCMD(Q_XSETQLIM,XFS_USER_QUOTA), bdev, id.uid, (caddr_t)&D); + ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (caddr_t)&D); break; #ifdef HAVE_GROUP_QUOTA case SMB_GROUP_QUOTA_TYPE: + DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", + path, bdev, (unsigned)id.gid)); + D.d_fieldmask |= FS_DQ_LIMIT_MASK; - ret = quotactl(QCMD(Q_XSETQLIM,XFS_GROUP_QUOTA), bdev, id.gid, (caddr_t)&D); + ret = quotactl(QCMD(Q_XSETQLIM,GRPQUOTA), bdev, id.gid, (caddr_t)&D); break; #endif /* HAVE_GROUP_QUOTA */ case SMB_USER_FS_QUOTA_TYPE: - quotactl(QCMD(Q_XGETQSTAT,XFS_USER_QUOTA), bdev, -1, (caddr_t)&F); + DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", + path, bdev, (unsigned)id.uid)); + + quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F); if (qflags & QUOTAS_DENY_DISK) { if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD)) @@ -193,7 +217,7 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt q_on |= XFS_QUOTA_UDQ_ACCT; if (q_on != 0) { - ret = quotactl(QCMD(Q_XQUOTAON,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_on); + ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on); } else { ret = 0; } @@ -203,7 +227,7 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt q_off |= XFS_QUOTA_UDQ_ENFD; if (q_off != 0) { - ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_off); + ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off); } else { ret = 0; } @@ -212,7 +236,7 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt q_on |= XFS_QUOTA_UDQ_ACCT; if (q_on != 0) { - ret = quotactl(QCMD(Q_XQUOTAON,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_on); + ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on); } else { ret = 0; } @@ -227,7 +251,7 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt q_off |= XFS_QUOTA_UDQ_ACCT; if (q_off !=0) { - ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_off); + ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off); } else { ret = 0; } @@ -239,7 +263,10 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt break; #ifdef HAVE_GROUP_QUOTA case SMB_GROUP_FS_QUOTA_TYPE: - quotactl(QCMD(Q_XGETQSTAT,XFS_GROUP_QUOTA), bdev, -1, (caddr_t)&F); + DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", + path, bdev, (unsigned)id.gid)); + + quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F); if (qflags & QUOTAS_DENY_DISK) { if (!(F.qs_flags & XFS_QUOTA_GDQ_ENFD)) @@ -248,7 +275,7 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt q_on |= XFS_QUOTA_GDQ_ACCT; if (q_on != 0) { - ret = quotactl(QCMD(Q_XQUOTAON,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_on); + ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on); } else { ret = 0; } @@ -258,7 +285,7 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt q_off |= XFS_QUOTA_GDQ_ENFD; if (q_off != 0) { - ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_off); + ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off); } else { ret = 0; } @@ -267,7 +294,7 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt q_on |= XFS_QUOTA_GDQ_ACCT; if (q_on != 0) { - ret = quotactl(QCMD(Q_XQUOTAON,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_on); + ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on); } else { ret = 0; } @@ -282,7 +309,7 @@ int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qt q_off |= XFS_QUOTA_GDQ_ACCT; if (q_off !=0) { - ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_off); + ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off); } else { ret = 0; } diff --git a/source3/smbd/ntquotas.c b/source3/smbd/ntquotas.c index 88d7c4e164..555f32d773 100644 --- a/source3/smbd/ntquotas.c +++ b/source3/smbd/ntquotas.c @@ -20,6 +20,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_QUOTA + static SMB_BIG_UINT limit_nt2unix(SMB_BIG_UINT in, SMB_BIG_UINT bsize) { SMB_BIG_UINT ret = (SMB_BIG_UINT)0; diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c index 19f225e973..c0b2db6173 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -27,6 +27,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_QUOTA + #ifndef HAVE_SYS_QUOTAS /* just a quick hack because sysquotas.h is included before linux/quota.h */ @@ -82,10 +85,10 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, gid_t egrp_id, LI ZERO_STRUCT(D); - ret = quotactl(QCMD(Q_XGETQUOTA,XFS_USER_QUOTA), path, euser_id, (caddr_t)&D); + ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); if (ret) - ret = quotactl(QCMD(Q_XGETQUOTA,XFS_GROUP_QUOTA), path, egrp_id, (caddr_t)&D); + ret = quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D); if (ret) return ret; @@ -1195,7 +1198,8 @@ BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BI unid_t id; id.uid = geteuid(); - + + ZERO_STRUCT(D); r=sys_get_quota(path, SMB_USER_QUOTA_TYPE, id, &D); /* Use softlimit to determine disk space, except when it has been exceeded */ @@ -1231,9 +1235,9 @@ BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BI return True; try_group_quota: -#ifdef HAVE_GROUP_QUOTA id.gid = getegid(); - + + ZERO_STRUCT(D); r=sys_get_quota(path, SMB_GROUP_QUOTA_TYPE, id, &D); /* Use softlimit to determine disk space, except when it has been exceeded */ @@ -1267,8 +1271,5 @@ try_group_quota: } return (True); -#else /* HAVE_GROUP_QUOTA */ - return False; -#endif /* HAVE_GROUP_QUOTA */ } #endif /* HAVE_SYS_QUOTAS */ -- cgit From fc1590abd991b657ff2510d8b48be271b4863294 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Jan 2004 09:08:38 +0000 Subject: merge: * Fix sys_chown() when no chown() is presend metze (This used to be commit ecf5b78248e551f3586967046d8b1da9bbe11e7b) --- source3/lib/system.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/lib/system.c b/source3/lib/system.c index 16384c8bdf..a0007ec83c 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -490,6 +490,8 @@ int sys_chown(const char *fname,uid_t uid,gid_t gid) DEBUG(1,("WARNING: no chown!\n")); done=1; } + errno = ENOSYS; + return -1; #else return(chown(fname,uid,gid)); #endif -- cgit From 1052d79b33292fba01266afbc493c34dfddba2d7 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Thu, 15 Jan 2004 09:50:47 +0000 Subject: Remove unused function. rafal (This used to be commit 2d2c36cc3f691f31506fbd97e74cf225a2ef85c5) --- source3/passdb/secrets.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index b389e42b7f..7317a4cf06 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -326,19 +326,6 @@ BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd, return True; } -/************************************************************************ - Routine to set the trust account password for a domain. -************************************************************************/ - -BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16]) -{ - struct machine_acct_pass pass; - - pass.mod_time = time(NULL); - memcpy(pass.hash, new_pwd, 16); - - return secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass)); -} /** * Routine to store the password for trusted domain -- cgit From feebffb12f04580bbed0377f3171abf188d2e519 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Thu, 15 Jan 2004 09:52:29 +0000 Subject: Remove unused variables. rafal (This used to be commit a284082716bf63569e5921eb33b1ecd1a9b4810d) --- source3/passdb/pdb_interface.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 26cbb21ee9..3592d5f0fd 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -440,7 +440,6 @@ static NTSTATUS context_add_trust_passwd(struct pdb_context *context, SAM_TRUST_PASSWD *trust) { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct pdb_methods *methods; if (!context) { DEBUG(0, ("invalid pdb_context specified!\n")); @@ -454,7 +453,6 @@ static NTSTATUS context_update_trust_passwd(struct pdb_context *context, SAM_TRUST_PASSWD *trust) { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct pdb_methods *methods; if (!context) { DEBUG(0, ("invalid pdb_context specified!\n")); @@ -473,7 +471,6 @@ static NTSTATUS context_delete_trust_passwd(struct pdb_context *context, SAM_TRUST_PASSWD *trust) { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct pdb_methods *methods; if (!context) { DEBUG(0, ("invalid pdb_context specified!\n")); -- cgit From a758fd958c808211fa3fa4556fc81fefcf876298 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 15 Jan 2004 17:19:20 +0000 Subject: reply_spnego_kerberos did not set the domain of the user handed to register_vuid correctly. We ended up with the local netbios name in substitutions for %D later. Volker P.S: Tridge, I can *really* see why you want to get rid of global variables :-) (This used to be commit 05bfaa858f8253b02fe0f78f97fb665e6847585d) --- source3/smbd/sesssetup.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 80be9da53b..9405c065e1 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -262,6 +262,13 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(ret); } + /* make_server_info_pw does not set the domain. Without this we end up + * with the local netbios name in substitutions for %D. */ + + if (server_info->sam_account != NULL) { + pdb_set_domain(server_info->sam_account, domain, PDB_SET); + } + /* register_vuid keeps the server info */ sess_vuid = register_vuid(server_info, session_key, nullblob, client); -- cgit From fbe657a40848d8a5a1a794d752c8115835322e01 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Jan 2004 17:23:49 +0000 Subject: BUG 958; don't use the -N option when invoking smbclient from the smbtar script (This used to be commit cb463b8fc9476695507fa996b508d98f1cf1e3ac) --- source3/script/smbtar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/script/smbtar b/source3/script/smbtar index f062cba9f0..67a794553c 100644 --- a/source3/script/smbtar +++ b/source3/script/smbtar @@ -161,5 +161,5 @@ fi tarargs=${tarargs}${blocksizearg}${newerarg} eval $SMBCLIENT "'\\\\$server\\$service'" "'$password'" -U "'$username'" \ --E -N $log -D "'$cdcmd'" ${clientargs} \ +-E $log -D "'$cdcmd'" ${clientargs} \ -T${tarcmd}${tarargs} $blocksize $newer $tapefile '${1+"$@"}' $verbose -- cgit From 341699b0053c18bfaf5b8c1aec63e3e16f965876 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Jan 2004 19:08:45 +0000 Subject: * BUG 446 - setup_logging() in smbclient to be interactive (remove the timestamps) - Fix bad return value in pull_ucs2( needs more testing to make sure this didn't break something else) that caused clistr_pull() to always read the same string from the buffer (pull_usc2() could return -1 if the original source length was given as -1) - increment some debugging messages to avoid printing them out so often (This used to be commit f452585073fbeeae3e3a0db644e381f94cb918f3) --- source3/client/client.c | 3 ++- source3/lib/charcnv.c | 4 ++++ source3/libsmb/cliconnect.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 5ee6913374..6c43a974f2 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2816,7 +2816,8 @@ static void remember_query_host(const char *arg, set_global_myworkgroup( "" ); /* set default debug level to 0 regardless of what smb.conf sets */ - DEBUGLEVEL_CLASS[DBGC_ALL] = 0; + setup_logging( "smbclient", True ); + DEBUGLEVEL_CLASS[DBGC_ALL] = 1; dbf = x_stderr; x_setbuf( x_stderr, NULL ); diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 1c6058a43e..5f9392b620 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -940,6 +940,10 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_ src_len &= ~1; ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len); + + if (src_len == (size_t)-1) + src_len = ret*2; + if (dest_len) dest[MIN(ret, dest_len-1)] = 0; else diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 707a33881d..84159e5d62 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -673,7 +673,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, BOOL got_kerberos_mechanism = False; DATA_BLOB blob; - DEBUG(2,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); + DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); /* the server might not even do spnego */ if (cli->secblob.length <= 16) { -- cgit From e367f403851ba3bdb1912fb6c89c478241c016d4 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 15 Jan 2004 19:49:57 +0000 Subject: Fix net rpc join (at least newstyle) after it was broken by changing the parms to cli_lsa_query_info_policy without changing them here... (This used to be commit 97d6f4752572cc10894e6e80379c25f5da143ad1) --- source3/utils/net_rpc_join.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index 96943468ad..eb91a7df61 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -109,7 +109,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) /* rpc variables */ POLICY_HND lsa_pol, sam_pol, domain_pol, user_pol; - DOM_SID domain_sid; + DOM_SID *domain_sid; uint32 user_rid; /* Password stuff */ @@ -127,7 +127,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) NTSTATUS result; int retval = 1; - fstring domain; + char *domain; uint32 num_rids, *name_types, *user_rids; uint32 flags = 0x3e8; char *acct_name; @@ -178,7 +178,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) "error opening lsa policy handle"); CHECK_RPC_ERR(cli_lsa_query_info_policy(cli, mem_ctx, &lsa_pol, - 5, domain, &domain_sid), + 5, &domain, &domain_sid), "error querying info policy"); cli_lsa_close(cli, mem_ctx, &lsa_pol); @@ -199,7 +199,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) CHECK_RPC_ERR(cli_samr_open_domain(cli, mem_ctx, &sam_pol, SEC_RIGHTS_MAXIMUM_ALLOWED, - &domain_sid, &domain_pol), + domain_sid, &domain_pol), "could not open domain"); /* Create domain user */ @@ -339,7 +339,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) strupper_m(domain); - if (!secrets_store_domain_sid(domain, &domain_sid)) { + if (!secrets_store_domain_sid(domain, domain_sid)) { DEBUG(0, ("error storing domain sid for %s\n", domain)); goto done; } -- cgit From e51bba51a38f736b5eee011208a2664978dd8f70 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Jan 2004 20:51:31 +0000 Subject: Bug 381: check builtin (not local) group SID. Patch from Jianliang Lu (This used to be commit 59cabc5b940990352ebd0ceef8b6e85ac04669c4) --- source3/rpc_server/srv_samr_nt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 7edd34c8dd..082e550928 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3365,7 +3365,7 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD } else { if (sid_compare(&alias_sid, &global_sid_Builtin)>0) { DEBUG(10, ("adding member on BUILTIN SID\n")); - if( !get_local_group_from_sid(&alias_sid, &map)) + if( !get_builtin_group_from_sid(&alias_sid, &map)) return NT_STATUS_NO_SUCH_ALIAS; } else -- cgit From 91dd593ad14801bc5d5e31d3b14b4989264b95fc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 16 Jan 2004 15:02:30 +0000 Subject: Patch from "Stoian Ivanov" : Add -g (greppable..) to smbclient -L to make the output usable in pipes. Volker (This used to be commit 190beff495742d8e45f5e3621ece74c33570d31a) --- source3/client/client.c | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 6c43a974f2..22d7260b8f 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -39,6 +39,7 @@ static pstring username; static pstring password; static BOOL use_kerberos; static BOOL got_pass; +static BOOL grepable=False; static char *cmdstr = NULL; static int io_bufsize = 64512; @@ -2001,8 +2002,12 @@ static void browse_fn(const char *name, uint32 m, /* FIXME: If the remote machine returns non-ascii characters in any of these fields, they can corrupt the output. We should remove them. */ - d_printf("\t%-15.15s%-10.10s%s\n", - name,typestr,comment); + if (!grepable) { + d_printf("\t%-15.15s%-10.10s%s\n", + name,typestr,comment); + } else { + d_printf ("%s|%s|%s\n",typestr,name,comment); + } } /**************************************************************************** @@ -2012,9 +2017,10 @@ static void browse_fn(const char *name, uint32 m, static BOOL browse_host(BOOL sort) { int ret; - - d_printf("\n\tSharename Type Comment\n"); - d_printf("\t--------- ---- -------\n"); + if (!grepable) { + d_printf("\n\tSharename Type Comment\n"); + d_printf("\t--------- ---- -------\n"); + } if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1) d_printf("Error returning browse list: %s\n", cli_errstr(cli)); @@ -2029,27 +2035,37 @@ static BOOL browse_host(BOOL sort) static void server_fn(const char *name, uint32 m, const char *comment, void *state) { - d_printf("\t%-16.16s %s\n", name, comment); + + if (!grepable){ + d_printf("\t%-16.16s %s\n", name, comment); + } else { + d_printf("%s|%s|%s\n",(char *)state, name, comment); + } } /**************************************************************************** Try and browse available connections on a host. ****************************************************************************/ -static BOOL list_servers(char *wk_grp) +static BOOL list_servers(const char *wk_grp) { if (!cli->server_domain) return False; - - d_printf("\n\tServer Comment\n"); - d_printf("\t--------- -------\n"); - cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn, NULL); + if (!grepable) { + d_printf("\n\tServer Comment\n"); + d_printf("\t--------- -------\n"); + }; + cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn, + "Server"); - d_printf("\n\tWorkgroup Master\n"); - d_printf("\t--------- -------\n"); + if (!grepable) { + d_printf("\n\tWorkgroup Master\n"); + d_printf("\t--------- -------\n"); + }; - cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, server_fn, NULL); + cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, + server_fn, "Workgroup"); return True; } @@ -2794,6 +2810,7 @@ static void remember_query_host(const char *arg, { "command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated commands" }, { "send-buffer", 'b', POPT_ARG_INT, &io_bufsize, 'b', "Changes the transmit/send buffer", "BYTES" }, { "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to", "PORT" }, + { "grepable", 'g', POPT_ARG_NONE, NULL, 'g', "Produce grepable output" }, POPT_COMMON_SAMBA POPT_COMMON_CONNECTION POPT_COMMON_CREDENTIALS @@ -2887,6 +2904,9 @@ static void remember_query_host(const char *arg, case 'D': fstrcpy(base_directory,poptGetOptArg(pc)); break; + case 'g': + grepable=True; + break; } } -- cgit From 8001e0e84c174cd4bc184d9daaa49c03fef085c5 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 16 Jan 2004 15:09:20 +0000 Subject: Fix another join problem. Don't use a TALLOC_CTX before it has been initialized. Also split out the oldstyle join into a new fn, allowing us to call it with no failure message from net rpc join, but displaying a failure message when used with net rpc oldjoin. (This used to be commit cab0a4c4d5c7bf9d89697bf1d351eafbd00d7fd2) --- source3/utils/net_rpc.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 9f0f64edec..93c13bf1f5 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -118,8 +118,6 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co return -1; } - domain_sid = net_get_remote_domain_sid(cli, mem_ctx); - /* Create mem_ctx */ if (!(mem_ctx = talloc_init("run_rpc_command"))) { @@ -128,6 +126,8 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co return -1; } + domain_sid = net_get_remote_domain_sid(cli, mem_ctx); + if (!cli_nt_session_open(cli, pipe_idx)) { DEBUG(0, ("Could not initialise pipe\n")); } @@ -276,7 +276,7 @@ static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, struct cli_stat * @return A shell status integer (0 for success) **/ -static int net_rpc_oldjoin(int argc, const char **argv) +static int net_rpc_perform_oldjoin(int argc, const char **argv) { return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, @@ -284,6 +284,27 @@ static int net_rpc_oldjoin(int argc, const char **argv) argc, argv); } +/** + * Join a domain, the old way. This function exists to allow + * the message to be displayed when oldjoin was explicitly + * requested, but not when it was implied by "net rpc join" + * + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ + +static int net_rpc_oldjoin(int argc, const char **argv) +{ + int rc = net_rpc_perform_oldjoin(argc, argv); + + if (rc) { + d_printf("Failed to join domain\n"); + } +} + /** * Basic usage function for 'net rpc join' * @param argc Standard main() style argc @@ -319,7 +340,7 @@ static int rpc_join_usage(int argc, const char **argv) int net_rpc_join(int argc, const char **argv) { - if ((net_rpc_oldjoin(argc, argv) == 0)) + if ((net_rpc_perform_oldjoin(argc, argv) == 0)) return 0; return net_rpc_join_newstyle(argc, argv); -- cgit From 65ed5b5f6e52780706e1fcc30a39741a43aa3342 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 16 Jan 2004 22:16:24 +0000 Subject: fix another bug caused by cli_lsa_query_info_policy() changes (This used to be commit f9664523282f3e92ff4d7641aded46fdf794aa5b) --- source3/rpcclient/rpcclient.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 0b60dea2fa..8372b75b4b 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -124,9 +124,10 @@ static void fetch_machine_sid(struct cli_state *cli) POLICY_HND pol; NTSTATUS result = NT_STATUS_OK; uint32 info_class = 5; - fstring domain_name; + char *domain_name = NULL; static BOOL got_domain_sid; TALLOC_CTX *mem_ctx; + DOM_SID *dom_sid = NULL; if (got_domain_sid) return; @@ -150,12 +151,13 @@ static void fetch_machine_sid(struct cli_state *cli) } result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, - domain_name, &domain_sid); + &domain_name, &dom_sid); if (!NT_STATUS_IS_OK(result)) { goto error; } got_domain_sid = True; + sid_copy( &domain_sid, dom_sid ); cli_lsa_close(cli, mem_ctx, &pol); cli_nt_session_close(cli); -- cgit From c0beb062c1b75435f7991f75202b9d99bb9989ba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Jan 2004 00:30:28 +0000 Subject: Fix for a signing bug when the mid wraps. Found by Fran Fabrizio . Add to the *start* of the list not the end of the list. This ensures that the *last* send sequence with this mid is returned by preference. This can happen if the mid wraps and one of the early mid numbers didn't get a reply and is still lurking on the list. Jeremy. (This used to be commit b84d249e67315c153e0aa3c5c9adfcf6ca008f97) --- source3/libsmb/smb_signing.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 8a056f659f..9010dbf5cb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -46,15 +46,23 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, uint16 mid, uint32 reply_seq_num) { struct outstanding_packet_lookup *t; - struct outstanding_packet_lookup *tmp; - + t = smb_xmalloc(sizeof(*t)); ZERO_STRUCTP(t); - DLIST_ADD_END(*list, t, tmp); t->mid = mid; t->reply_seq_num = reply_seq_num; + /* + * Add to the *start* of the list not the end of the list. + * This ensures that the *last* send sequence with this mid + * is returned by preference. + * This can happen if the mid wraps and one of the early + * mid numbers didn't get a reply and is still lurking on + * the list. JRA. Found by Fran Fabrizio . + */ + + DLIST_ADD(*list, t); DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", (unsigned int)reply_seq_num, (unsigned int)mid )); } -- cgit From e25e0e372bfd3afbab0e116d61a48bbcb934203d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 19 Jan 2004 08:52:53 +0000 Subject: 1. The most part of this patch changed the unknown_3 flag to the now known meaning of fields_present bit mask. Also avoid it being saved in backends (0 is saved where removing the unit32 would have produced a format change). Also add support in samr functions to correctly interpret the flags. Flags still not set properly (eg. still set all flags 0xffffff as previous code), need a tool to test this properly (I',ve done preliminary tests with samba4 rpc torture and it seem to work properly against w2k). 2. Patch for handlig the flag user must change password at next logon in usrmgr based on Jianliang Lu patch (This used to be commit 78975e9483e64412e436c5dbfe2b71e20b79de29) --- source3/Makefile.in | 2 +- source3/include/gums.h | 92 ++--- source3/include/passdb.h | 38 +- source3/include/rpc_samr.h | 5 +- source3/include/tdbsam2.h | 150 -------- source3/include/tdbsam2_parse_info.h | 225 +++++------- source3/passdb/passdb.c | 20 +- source3/passdb/pdb_get_set.c | 26 +- source3/passdb/pdb_gums.c | 7 +- source3/passdb/pdb_ldap.c | 2 - source3/passdb/pdb_mysql.c | 1 - source3/passdb/pdb_pgsql.c | 1 - source3/passdb/pdb_sql.c | 3 - source3/passdb/pdb_xml.c | 6 - source3/rpc_parse/parse_samr.c | 36 +- source3/rpc_server/srv_samr_util.c | 274 +++++++++------ source3/rpcclient/cmd_samr.c | 2 +- source3/sam/gums_api.c | 20 -- source3/sam/gums_helper.c | 6 +- source3/sam/gums_tdbsam2.c | 651 +++++++++++++++-------------------- 20 files changed, 673 insertions(+), 894 deletions(-) delete mode 100644 source3/include/tdbsam2.h diff --git a/source3/Makefile.in b/source3/Makefile.in index 1bd3392f02..6d69e03e5f 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1423,7 +1423,7 @@ include/tdbsam2_parse_info.h: @if test -n "$(PERL)"; then \ cd $(srcdir) && @PERL@ -w script/genstruct.pl \ -o include/tdbsam2_parse_info.h $(CC) -E -O2 -g \ - include/tdbsam2.h; \ + include/gums.h; \ else \ echo Unable to build $@, continuing; \ fi diff --git a/source3/include/gums.h b/source3/include/gums.h index 9ce2ec4e56..d16a839bc4 100644 --- a/source3/include/gums.h +++ b/source3/include/gums.h @@ -24,13 +24,13 @@ #define GUMS_VERSION_MAJOR 0 #define GUMS_VERSION_MINOR 1 #define GUMS_OBJECT_VERSION 1 +#define GUMS_PRIVILEGE_VERSION 1 #define GUMS_INTERFACE_VERSION 1 #define GUMS_OBJ_DOMAIN 0x10 #define GUMS_OBJ_NORMAL_USER 0x20 #define GUMS_OBJ_GROUP 0x30 #define GUMS_OBJ_ALIAS 0x31 -#define GUMS_OBJ_PRIVILEGE 0x40 /* define value types */ #define GUMS_SET_PRIMARY_GROUP 0x1 @@ -79,7 +79,7 @@ #define GUMS_DEL_SID_LIST 0x61 #define GUMS_SET_SID_LIST 0x62 -typedef struct gums_user +GENSTRUCT struct gums_user { DOM_SID *group_sid; /* Primary Group SID */ @@ -90,14 +90,14 @@ typedef struct gums_user NTTIME pass_can_change_time; /* password can change time */ NTTIME pass_must_change_time; /* password must change time */ - char *full_name; /* user's full name string */ - char *home_dir; /* home directory string */ - char *dir_drive; /* home directory drive string */ - char *logon_script; /* logon script string */ - char *profile_path; /* profile path string */ - char *workstations; /* login from workstations string */ - char *unknown_str; /* don't know what this is, yet. */ - char *munged_dial; /* munged path name and dial-back tel number */ + char *full_name; _NULLTERM /* user's full name string */ + char *home_dir; _NULLTERM /* home directory string */ + char *dir_drive; _NULLTERM /* home directory drive string */ + char *logon_script; _NULLTERM /* logon script string */ + char *profile_path; _NULLTERM /* profile path string */ + char *workstations; _NULLTERM /* login from workstations string */ + char *unknown_str; _NULLTERM /* don't know what this is, yet. */ + char *munged_dial; _NULLTERM /* munged path name and dial-back tel number */ DATA_BLOB lm_pw; /* .data is Null if no password */ DATA_BLOB nt_pw; /* .data is Null if no password */ @@ -105,61 +105,70 @@ typedef struct gums_user uint16 acct_ctrl; /* account type & status flags */ uint16 logon_divs; /* 168 - number of hours in a week */ uint32 hours_len; /* normally 21 bytes */ - uint8 *hours; + uint8 *hours; _LEN(hours_len) /* normally 21 bytes (depends on hours_len) */ uint16 bad_password_count; /* 0 */ uint16 logon_count; /* 0 */ uint32 unknown_3; /* 0x00ff ffff */ uint32 unknown_6; /* 0x0000 04ec */ -} GUMS_USER; +}; -typedef struct gums_group +GENSTRUCT struct gums_group { uint32 count; /* Number of SIDs */ - DOM_SID *members; /* SID array */ + DOM_SID *members; _LEN(count) /* SID array */ -} GUMS_GROUP; +}; -typedef struct gums_domain +GENSTRUCT struct gums_domain { uint32 next_rid; -} GUMS_DOMAIN; +}; -typedef struct gums_privilege +GENSTRUCT struct gums_object { - LUID_ATTR *privilege; /* Privilege Type */ + TALLOC_CTX *mem_ctx; - uint32 count; - DOM_SID *members; + uint32 type; /* Object Type */ + uint32 version; /* Object Version */ + uint32 seq_num; /* Object Sequence Number */ + + SEC_DESC *sec_desc; /* Security Descriptor */ + + DOM_SID *sid; /* Object Sid */ + char *name; _NULLTERM /* Object Name - it should be in DOMAIN\NAME format */ + char *description; _NULLTERM /* Object Description */ -} GUMS_PRIVILEGE; + struct gums_user *user; + struct gums_group *group; + struct gums_domain *domain; -union gums_obj_p { - GUMS_USER *user; - GUMS_GROUP *group; - GUMS_DOMAIN *domain; - GUMS_PRIVILEGE *priv; }; -typedef struct gums_object +GENSTRUCT struct gums_privilege { TALLOC_CTX *mem_ctx; - uint32 type; /* Object Type */ uint32 version; /* Object Version */ uint32 seq_num; /* Object Sequence Number */ - SEC_DESC *sec_desc; /* Security Descriptor */ + char *name; _NULLTERM /* Object Name */ + char *description; _NULLTERM /* Object Description */ - DOM_SID *sid; /* Object Sid */ - char *name; /* Object Name */ - char *description; /* Object Description */ + LUID_ATTR *privilege; /* Privilege Type */ - union gums_obj_p data; /* Object Specific data */ + uint32 count; + DOM_SID *members; _LEN(count) + +}; -} GUMS_OBJECT; +typedef struct gums_user GUMS_USER; +typedef struct gums_group GUMS_GROUP; +typedef struct gums_domain GUMS_DOMAIN; +typedef struct gums_object GUMS_OBJECT; +typedef struct gums_privilege GUMS_PRIVILEGE; typedef struct gums_data_set { @@ -210,7 +219,7 @@ typedef struct gums_functions NTSTATUS (*delete_object) (const DOM_SID *sid); NTSTATUS (*get_object_from_sid) (GUMS_OBJECT **object, const DOM_SID *sid, const int obj_type); - NTSTATUS (*get_object_from_name) (GUMS_OBJECT **object, const char *name, const int obj_type); + NTSTATUS (*get_object_from_name) (GUMS_OBJECT **object, const char *domain, const char *name, const int obj_type); /* This function is used to get the list of all objects changed since b_time, it is used to support PDC<->BDC synchronization */ NTSTATUS (*get_updated_objects) (GUMS_OBJECT **objects, const NTTIME base_time); @@ -221,7 +230,7 @@ typedef struct gums_functions /* This function MUST be used ONLY by PDC<->BDC replication code or recovery tools. Never use this function to update an object in the database, use set_object_values() */ - NTSTATUS (*set_object) (const GUMS_OBJECT *object); + NTSTATUS (*set_object) (GUMS_OBJECT *object); /* set object values function */ NTSTATUS (*set_object_values) (DOM_SID *sid, uint32 count, GUMS_DATA_SET *data_set); @@ -238,10 +247,11 @@ typedef struct gums_functions /* privileges related functions */ - NTSTATUS (*add_members_to_privilege) (const LUID_ATTR *priv, const DOM_SID **members); - NTSTATUS (*delete_members_from_privilege) (const LUID_ATTR *priv, const DOM_SID **members); - NTSTATUS (*enumerate_privilege_members) (DOM_SID **members, const LUID_ATTR *priv); - NTSTATUS (*get_sid_privileges) (DOM_SID **privs, const DOM_SID *sid); + NTSTATUS (*get_privilege) (GUMS_OBJECT **object, const char *name); + NTSTATUS (*add_members_to_privilege) (const char *name, const DOM_SID **members); + NTSTATUS (*delete_members_from_privilege) (const char *name, const DOM_SID **members); + NTSTATUS (*enumerate_privilege_members) (const char *name, DOM_SID **members); + NTSTATUS (*get_sid_privileges) (const DOM_SID *sid, const char **privs); /* warning!: set_privilege will overwrite a prior existing privilege if such exist */ NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv); diff --git a/source3/include/passdb.h b/source3/include/passdb.h index c12cf10cf2..add286816c 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -25,6 +25,42 @@ #define _PASSDB_H +/* + * fields_present flags meanings + * same names as found in samba4 idl files + */ + +#define ACCT_USERNAME 0x00000001 +#define ACCT_FULL_NAME 0x00000002 +#define ACCT_RID 0x00000004 +#define ACCT_PRIMARY_GID 0x00000008 +#define ACCT_ADMIN_DESC 0x00000010 +#define ACCT_DESCRIPTION 0x00000020 +#define ACCT_HOME_DIR 0x00000040 +#define ACCT_HOME_DRIVE 0x00000080 +#define ACCT_LOGON_SCRIPT 0x00000100 +#define ACCT_PROFILE 0x00000200 +#define ACCT_WORKSTATIONS 0x00000400 +#define ACCT_LAST_LOGON 0x00000800 +#define ACCT_LAST_LOGOFF 0x00001000 +#define ACCT_LOGON_HOURS 0x00002000 +#define ACCT_BAD_PWD_COUNT 0x00004000 +#define ACCT_NUM_LOGONS 0x00008000 +#define ACCT_ALLOW_PWD_CHANGE 0x00010000 +#define ACCT_FORCE_PWD_CHANGE 0x00020000 +#define ACCT_LAST_PWD_CHANGE 0x00040000 +#define ACCT_EXPIRY 0x00080000 +#define ACCT_FLAGS 0x00100000 +#define ACCT_CALLBACK 0x00200001 +#define ACCT_COUNTRY_CODE 0x00400000 +#define ACCT_CODE_PAGE 0x00800000 +#define ACCT_NT_PWD_SET 0x01000000 +#define ACCT_LM_PWD_SET 0x02000000 +#define ACCT_PRIVATEDATA 0x04000000 +#define ACCT_EXPIRED_FLAG 0x08000000 +#define ACCT_SEC_DESC 0x10000000 +#define ACCT_OWF_PWD 0x20000000 + /* * bit flags representing initialized fields in SAM_ACCOUNT */ @@ -140,7 +176,7 @@ typedef struct sam_passwd char* plaintext_pw; /* is Null if not available */ uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */ - uint32 unknown_3; /* 0x00ff ffff */ + uint32 fields_present; /* 0x00ff ffff */ uint16 logon_divs; /* 168 - number of hours in a week */ uint32 hours_len; /* normally 21 bytes */ diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index 787535d0e9..a8ca504c8f 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -183,7 +183,7 @@ typedef struct sam_user_info_23 uint32 acb_info; /* account info (ACB_xxxx bit-mask) */ - uint32 unknown_3; /* 0x09f8 27fa */ + uint32 fields_present; /* 0x09f8 27fa */ uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */ /* uint8 pad[2] */ @@ -308,7 +308,8 @@ typedef struct sam_user_info_21 uint32 acb_info; /* account info (ACB_xxxx bit-mask) */ - uint32 unknown_3; /* 0x00ff ffff */ + /* Was unknown_3 */ + uint32 fields_present; /* 0x00ff ffff */ uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */ /* uint8 pad[2] */ diff --git a/source3/include/tdbsam2.h b/source3/include/tdbsam2.h deleted file mode 100644 index b99e16586b..0000000000 --- a/source3/include/tdbsam2.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * tdbsam2 genstruct enabled header file - * Copyright (C) Simo Sorce 2002 - * - * 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 the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 675 - * Mass Ave, Cambridge, MA 02139, USA. - */ - -/* ALL strings assumes UTF8 as encoding */ - -#ifndef TDBSAM2_H -#define TDBSAM2_H - -/* IMPORTANT: these structures must follow closely the GUMS_OBJECTs - * structures as they will be casted over !! - * the GUMS_OBJECT union is unrolled here into four tdbsam2 - * objects cause genstruct is not able to follow arbitrary unions */ - -GENSTRUCT struct domain_sub_structure -{ - uint32 next_rid; /* The Next free RID */ -}; - -GENSTRUCT struct tdbsam2_domain_data -{ - TALLOC_CTX *mem_ctx; - - uint32 type; - uint32 version; - uint32 xcounter; /* counter to be updated at any change */ - - SEC_DESC *sec_desc; /* Security Descriptor */ - - DOM_SID *dom_sid; /* The Domain SID */ - char *name; _NULLTERM /* NT Domain Name */ - char *description; _NULLTERM /* Descritpion (Gecos) */ - - struct domain_sub_structure *dss; -}; - -GENSTRUCT struct user_sub_structure -{ - DOM_SID *group_sid; /* The Primary Group SID */ - - NTTIME logon_time; - NTTIME logoff_time; - NTTIME kickoff_time; - NTTIME pass_last_set_time; - NTTIME pass_can_change_time; - NTTIME pass_must_change_time; - - char *full_name; _NULLTERM /* The Full Name */ - char *home_dir; _NULLTERM /* Home Directory */ - char *dir_drive; _NULLTERM /* Drive Letter the home should be mapped to */ - char *logon_script; _NULLTERM /* Logon script path */ - char *profile_path; _NULLTERM /* Profile is stored here */ - char *workstations; _NULLTERM /* List of Workstation names the user is allowed to LogIn */ - char *unknown_str; _NULLTERM /* Guess ... Unknown */ - char *munged_dial; _NULLTERM /* Callback Number */ - - DATA_BLOB lm_pw; /* .data is Null if no password */ - DATA_BLOB nt_pw; /* .data is Null if no password */ - - uint16 acct_ctrl; /* account flags */ - uint16 logon_divs; /* 168 - num of hours in a week */ - uint32 hours_len; /* normally 21 */ - uint8 *hours; _LEN(hours_len) /* normally 21 bytes (depends on hours_len) */ - - uint16 bad_password_count; /* 0 */ - uint16 logon_count; /* 0 */ - uint32 unknown_3; /* 0x00ff ffff */ - uint32 unknown_6; /* 0x0000 04ec */ -}; - -GENSTRUCT struct tdbsam2_user_data -{ - TALLOC_CTX *mem_ctx; - - uint32 type; - uint32 version; - uint32 xcounter; /* counter to be updated at any change */ - - SEC_DESC *sec_desc; /* Security Descriptor */ - - DOM_SID *user_sid; /* The User SID */ - char *name; _NULLTERM /* NT User Name */ - char *description; _NULLTERM /* Descritpion (Gecos) */ - - struct user_sub_structure *uss; -}; - -GENSTRUCT struct group_sub_structure -{ - uint32 count; /* number of sids */ - DOM_SID *members; _LEN(count) /* SID array */ -}; - -GENSTRUCT struct tdbsam2_group_data -{ - TALLOC_CTX *mem_ctx; - - uint32 type; - uint32 version; - uint32 xcounter; /* counter to be updated at any change */ - - SEC_DESC *sec_desc; /* Security Descriptor */ - - DOM_SID *group_sid; /* The Group SID */ - char *name; _NULLTERM /* NT Group Name */ - char *description; _NULLTERM /* Descritpion (Gecos) */ - - struct group_sub_structure *gss; -}; - -GENSTRUCT struct priv_sub_structure -{ - LUID_ATTR *privilege; /* Privilege */ - - uint32 count; /* number of sids */ - DOM_SID *members; _LEN(count) /* SID array */ -}; - -GENSTRUCT struct tdbsam2_priv_data -{ - TALLOC_CTX *mem_ctx; - - uint32 type; - uint32 version; - uint32 xcounter; /* counter to be updated at any change */ - - DOM_SID *null_sid; - char *name; _NULLTERM /* Privilege Name */ - char *description; _NULLTERM /* Descritpion (Gecos) */ - - struct priv_sub_structure *pss; -}; - -#endif /* TDBSAM2_H */ diff --git a/source3/include/tdbsam2_parse_info.h b/source3/include/tdbsam2_parse_info.h index f1b2936c47..abaa2b142a 100644 --- a/source3/include/tdbsam2_parse_info.h +++ b/source3/include/tdbsam2_parse_info.h @@ -1,164 +1,109 @@ /* This is an automatically generated file - DO NOT EDIT! */ -int gen_dump_struct_domain_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_domain_sub_structure(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_domain_sub_structure[] = { -{"next_rid", 0, sizeof(uint32), offsetof(struct domain_sub_structure, next_rid), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +int gen_dump_struct_gums_user(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); +int gen_parse_struct_gums_user(TALLOC_CTX *mem_ctx, char *, const char *); +static const struct parse_struct pinfo_gums_user[] = { +{"group_sid", 1, sizeof(DOM_SID), offsetof(struct gums_user, group_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, +{"logon_time", 0, sizeof(NTTIME), offsetof(struct gums_user, logon_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, +{"logoff_time", 0, sizeof(NTTIME), offsetof(struct gums_user, logoff_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, +{"kickoff_time", 0, sizeof(NTTIME), offsetof(struct gums_user, kickoff_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, +{"pass_last_set_time", 0, sizeof(NTTIME), offsetof(struct gums_user, pass_last_set_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, +{"pass_can_change_time", 0, sizeof(NTTIME), offsetof(struct gums_user, pass_can_change_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, +{"pass_must_change_time", 0, sizeof(NTTIME), offsetof(struct gums_user, pass_must_change_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, +{"full_name", 1, sizeof(char), offsetof(struct gums_user, full_name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"home_dir", 1, sizeof(char), offsetof(struct gums_user, home_dir), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"dir_drive", 1, sizeof(char), offsetof(struct gums_user, dir_drive), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"logon_script", 1, sizeof(char), offsetof(struct gums_user, logon_script), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"profile_path", 1, sizeof(char), offsetof(struct gums_user, profile_path), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"workstations", 1, sizeof(char), offsetof(struct gums_user, workstations), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"unknown_str", 1, sizeof(char), offsetof(struct gums_user, unknown_str), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"munged_dial", 1, sizeof(char), offsetof(struct gums_user, munged_dial), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"lm_pw", 0, sizeof(DATA_BLOB), offsetof(struct gums_user, lm_pw), 0, NULL, 0, gen_dump_DATA_BLOB, gen_parse_DATA_BLOB}, +{"nt_pw", 0, sizeof(DATA_BLOB), offsetof(struct gums_user, nt_pw), 0, NULL, 0, gen_dump_DATA_BLOB, gen_parse_DATA_BLOB}, +{"acct_ctrl", 0, sizeof(uint16), offsetof(struct gums_user, acct_ctrl), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, +{"logon_divs", 0, sizeof(uint16), offsetof(struct gums_user, logon_divs), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, +{"hours_len", 0, sizeof(uint32), offsetof(struct gums_user, hours_len), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +{"hours", 1, sizeof(uint8), offsetof(struct gums_user, hours), 0, "hours_len", 0, gen_dump_uint8, gen_parse_uint8}, +{"bad_password_count", 0, sizeof(uint16), offsetof(struct gums_user, bad_password_count), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, +{"logon_count", 0, sizeof(uint16), offsetof(struct gums_user, logon_count), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, +{"unknown_3", 0, sizeof(uint32), offsetof(struct gums_user, unknown_3), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +{"unknown_6", 0, sizeof(uint32), offsetof(struct gums_user, unknown_6), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, {NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; -int gen_dump_struct_domain_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_domain_sub_structure, p, ptr, indent); +int gen_dump_struct_gums_user(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { + return gen_dump_struct(mem_ctx, pinfo_gums_user, p, ptr, indent); } -int gen_parse_struct_domain_sub_structure(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_domain_sub_structure, ptr, str); +int gen_parse_struct_gums_user(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { + return gen_parse_struct(mem_ctx, pinfo_gums_user, ptr, str); } -int gen_dump_struct_tdbsam2_domain_data(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_tdbsam2_domain_data(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_tdbsam2_domain_data[] = { -{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct tdbsam2_domain_data, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX}, -{"type", 0, sizeof(uint32), offsetof(struct tdbsam2_domain_data, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"version", 0, sizeof(uint32), offsetof(struct tdbsam2_domain_data, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"xcounter", 0, sizeof(uint32), offsetof(struct tdbsam2_domain_data, xcounter), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"sec_desc", 1, sizeof(SEC_DESC), offsetof(struct tdbsam2_domain_data, sec_desc), 0, NULL, 0, gen_dump_SEC_DESC, gen_parse_SEC_DESC}, -{"dom_sid", 1, sizeof(DOM_SID), offsetof(struct tdbsam2_domain_data, dom_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, -{"name", 1, sizeof(char), offsetof(struct tdbsam2_domain_data, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"description", 1, sizeof(char), offsetof(struct tdbsam2_domain_data, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"dss", 1, sizeof(struct domain_sub_structure), offsetof(struct tdbsam2_domain_data, dss), 0, NULL, 0, gen_dump_struct_domain_sub_structure, gen_parse_struct_domain_sub_structure}, +int gen_dump_struct_gums_group(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); +int gen_parse_struct_gums_group(TALLOC_CTX *mem_ctx, char *, const char *); +static const struct parse_struct pinfo_gums_group[] = { +{"count", 0, sizeof(uint32), offsetof(struct gums_group, count), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +{"members", 1, sizeof(DOM_SID), offsetof(struct gums_group, members), 0, "count", 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, {NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; -int gen_dump_struct_tdbsam2_domain_data(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_tdbsam2_domain_data, p, ptr, indent); +int gen_dump_struct_gums_group(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { + return gen_dump_struct(mem_ctx, pinfo_gums_group, p, ptr, indent); } -int gen_parse_struct_tdbsam2_domain_data(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_tdbsam2_domain_data, ptr, str); +int gen_parse_struct_gums_group(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { + return gen_parse_struct(mem_ctx, pinfo_gums_group, ptr, str); } -int gen_dump_struct_user_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_user_sub_structure(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_user_sub_structure[] = { -{"group_sid", 1, sizeof(DOM_SID), offsetof(struct user_sub_structure, group_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, -{"logon_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, logon_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"logoff_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, logoff_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"kickoff_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, kickoff_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"pass_last_set_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, pass_last_set_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"pass_can_change_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, pass_can_change_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"pass_must_change_time", 0, sizeof(NTTIME), offsetof(struct user_sub_structure, pass_must_change_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"full_name", 1, sizeof(char), offsetof(struct user_sub_structure, full_name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"home_dir", 1, sizeof(char), offsetof(struct user_sub_structure, home_dir), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"dir_drive", 1, sizeof(char), offsetof(struct user_sub_structure, dir_drive), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"logon_script", 1, sizeof(char), offsetof(struct user_sub_structure, logon_script), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"profile_path", 1, sizeof(char), offsetof(struct user_sub_structure, profile_path), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"workstations", 1, sizeof(char), offsetof(struct user_sub_structure, workstations), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"unknown_str", 1, sizeof(char), offsetof(struct user_sub_structure, unknown_str), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"munged_dial", 1, sizeof(char), offsetof(struct user_sub_structure, munged_dial), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"lm_pw", 0, sizeof(DATA_BLOB), offsetof(struct user_sub_structure, lm_pw), 0, NULL, 0, gen_dump_DATA_BLOB, gen_parse_DATA_BLOB}, -{"nt_pw", 0, sizeof(DATA_BLOB), offsetof(struct user_sub_structure, nt_pw), 0, NULL, 0, gen_dump_DATA_BLOB, gen_parse_DATA_BLOB}, -{"acct_ctrl", 0, sizeof(uint16), offsetof(struct user_sub_structure, acct_ctrl), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, -{"logon_divs", 0, sizeof(uint16), offsetof(struct user_sub_structure, logon_divs), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, -{"hours_len", 0, sizeof(uint32), offsetof(struct user_sub_structure, hours_len), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"hours", 1, sizeof(uint8), offsetof(struct user_sub_structure, hours), 0, "hours_len", 0, gen_dump_uint8, gen_parse_uint8}, -{"bad_password_count", 0, sizeof(uint16), offsetof(struct user_sub_structure, bad_password_count), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, -{"logon_count", 0, sizeof(uint16), offsetof(struct user_sub_structure, logon_count), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, -{"unknown_3", 0, sizeof(uint32), offsetof(struct user_sub_structure, unknown_3), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"unknown_6", 0, sizeof(uint32), offsetof(struct user_sub_structure, unknown_6), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +int gen_dump_struct_gums_domain(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); +int gen_parse_struct_gums_domain(TALLOC_CTX *mem_ctx, char *, const char *); +static const struct parse_struct pinfo_gums_domain[] = { +{"next_rid", 0, sizeof(uint32), offsetof(struct gums_domain, next_rid), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, {NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; -int gen_dump_struct_user_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_user_sub_structure, p, ptr, indent); -} -int gen_parse_struct_user_sub_structure(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_user_sub_structure, ptr, str); -} - -int gen_dump_struct_tdbsam2_user_data(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_tdbsam2_user_data(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_tdbsam2_user_data[] = { -{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct tdbsam2_user_data, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX}, -{"type", 0, sizeof(uint32), offsetof(struct tdbsam2_user_data, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"version", 0, sizeof(uint32), offsetof(struct tdbsam2_user_data, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"xcounter", 0, sizeof(uint32), offsetof(struct tdbsam2_user_data, xcounter), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"sec_desc", 1, sizeof(SEC_DESC), offsetof(struct tdbsam2_user_data, sec_desc), 0, NULL, 0, gen_dump_SEC_DESC, gen_parse_SEC_DESC}, -{"user_sid", 1, sizeof(DOM_SID), offsetof(struct tdbsam2_user_data, user_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, -{"name", 1, sizeof(char), offsetof(struct tdbsam2_user_data, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"description", 1, sizeof(char), offsetof(struct tdbsam2_user_data, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"uss", 1, sizeof(struct user_sub_structure), offsetof(struct tdbsam2_user_data, uss), 0, NULL, 0, gen_dump_struct_user_sub_structure, gen_parse_struct_user_sub_structure}, -{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; - -int gen_dump_struct_tdbsam2_user_data(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_tdbsam2_user_data, p, ptr, indent); -} -int gen_parse_struct_tdbsam2_user_data(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_tdbsam2_user_data, ptr, str); -} - -int gen_dump_struct_group_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_group_sub_structure(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_group_sub_structure[] = { -{"count", 0, sizeof(uint32), offsetof(struct group_sub_structure, count), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"members", 1, sizeof(DOM_SID), offsetof(struct group_sub_structure, members), 0, "count", 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, -{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; - -int gen_dump_struct_group_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_group_sub_structure, p, ptr, indent); -} -int gen_parse_struct_group_sub_structure(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_group_sub_structure, ptr, str); -} - -int gen_dump_struct_tdbsam2_group_data(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_tdbsam2_group_data(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_tdbsam2_group_data[] = { -{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct tdbsam2_group_data, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX}, -{"type", 0, sizeof(uint32), offsetof(struct tdbsam2_group_data, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"version", 0, sizeof(uint32), offsetof(struct tdbsam2_group_data, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"xcounter", 0, sizeof(uint32), offsetof(struct tdbsam2_group_data, xcounter), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"sec_desc", 1, sizeof(SEC_DESC), offsetof(struct tdbsam2_group_data, sec_desc), 0, NULL, 0, gen_dump_SEC_DESC, gen_parse_SEC_DESC}, -{"group_sid", 1, sizeof(DOM_SID), offsetof(struct tdbsam2_group_data, group_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, -{"name", 1, sizeof(char), offsetof(struct tdbsam2_group_data, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"description", 1, sizeof(char), offsetof(struct tdbsam2_group_data, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"gss", 1, sizeof(struct group_sub_structure), offsetof(struct tdbsam2_group_data, gss), 0, NULL, 0, gen_dump_struct_group_sub_structure, gen_parse_struct_group_sub_structure}, -{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; - -int gen_dump_struct_tdbsam2_group_data(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_tdbsam2_group_data, p, ptr, indent); -} -int gen_parse_struct_tdbsam2_group_data(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_tdbsam2_group_data, ptr, str); -} - -int gen_dump_struct_priv_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_priv_sub_structure(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_priv_sub_structure[] = { -{"privilege", 1, sizeof(LUID_ATTR), offsetof(struct priv_sub_structure, privilege), 0, NULL, 0, gen_dump_LUID_ATTR, gen_parse_LUID_ATTR}, -{"count", 0, sizeof(uint32), offsetof(struct priv_sub_structure, count), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"members", 1, sizeof(DOM_SID), offsetof(struct priv_sub_structure, members), 0, "count", 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, +int gen_dump_struct_gums_domain(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { + return gen_dump_struct(mem_ctx, pinfo_gums_domain, p, ptr, indent); +} +int gen_parse_struct_gums_domain(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { + return gen_parse_struct(mem_ctx, pinfo_gums_domain, ptr, str); +} + +int gen_dump_struct_gums_object(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); +int gen_parse_struct_gums_object(TALLOC_CTX *mem_ctx, char *, const char *); +static const struct parse_struct pinfo_gums_object[] = { +{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct gums_object, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX}, +{"type", 0, sizeof(uint32), offsetof(struct gums_object, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +{"version", 0, sizeof(uint32), offsetof(struct gums_object, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +{"seq_num", 0, sizeof(uint32), offsetof(struct gums_object, seq_num), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +{"sec_desc", 1, sizeof(SEC_DESC), offsetof(struct gums_object, sec_desc), 0, NULL, 0, gen_dump_SEC_DESC, gen_parse_SEC_DESC}, +{"sid", 1, sizeof(DOM_SID), offsetof(struct gums_object, sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, +{"name", 1, sizeof(char), offsetof(struct gums_object, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"description", 1, sizeof(char), offsetof(struct gums_object, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"user", 1, sizeof(struct gums_user), offsetof(struct gums_object, user), 0, NULL, 0, gen_dump_struct_gums_user, gen_parse_struct_gums_user}, +{"group", 1, sizeof(struct gums_group), offsetof(struct gums_object, group), 0, NULL, 0, gen_dump_struct_gums_group, gen_parse_struct_gums_group}, +{"domain", 1, sizeof(struct gums_domain), offsetof(struct gums_object, domain), 0, NULL, 0, gen_dump_struct_gums_domain, gen_parse_struct_gums_domain}, {NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; -int gen_dump_struct_priv_sub_structure(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_priv_sub_structure, p, ptr, indent); +int gen_dump_struct_gums_object(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { + return gen_dump_struct(mem_ctx, pinfo_gums_object, p, ptr, indent); } -int gen_parse_struct_priv_sub_structure(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_priv_sub_structure, ptr, str); +int gen_parse_struct_gums_object(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { + return gen_parse_struct(mem_ctx, pinfo_gums_object, ptr, str); } -int gen_dump_struct_tdbsam2_priv_data(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_tdbsam2_priv_data(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_tdbsam2_priv_data[] = { -{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct tdbsam2_priv_data, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX}, -{"type", 0, sizeof(uint32), offsetof(struct tdbsam2_priv_data, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"version", 0, sizeof(uint32), offsetof(struct tdbsam2_priv_data, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"xcounter", 0, sizeof(uint32), offsetof(struct tdbsam2_priv_data, xcounter), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"null_sid", 1, sizeof(DOM_SID), offsetof(struct tdbsam2_priv_data, null_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, -{"name", 1, sizeof(char), offsetof(struct tdbsam2_priv_data, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"description", 1, sizeof(char), offsetof(struct tdbsam2_priv_data, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"pss", 1, sizeof(struct priv_sub_structure), offsetof(struct tdbsam2_priv_data, pss), 0, NULL, 0, gen_dump_struct_priv_sub_structure, gen_parse_struct_priv_sub_structure}, +int gen_dump_struct_gums_privilege(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); +int gen_parse_struct_gums_privilege(TALLOC_CTX *mem_ctx, char *, const char *); +static const struct parse_struct pinfo_gums_privilege[] = { +{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct gums_privilege, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX}, +{"version", 0, sizeof(uint32), offsetof(struct gums_privilege, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +{"seq_num", 0, sizeof(uint32), offsetof(struct gums_privilege, seq_num), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +{"name", 1, sizeof(char), offsetof(struct gums_privilege, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"description", 1, sizeof(char), offsetof(struct gums_privilege, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, +{"privilege", 1, sizeof(LUID_ATTR), offsetof(struct gums_privilege, privilege), 0, NULL, 0, gen_dump_LUID_ATTR, gen_parse_LUID_ATTR}, +{"count", 0, sizeof(uint32), offsetof(struct gums_privilege, count), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, +{"members", 1, sizeof(DOM_SID), offsetof(struct gums_privilege, members), 0, "count", 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, {NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; -int gen_dump_struct_tdbsam2_priv_data(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_tdbsam2_priv_data, p, ptr, indent); +int gen_dump_struct_gums_privilege(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { + return gen_dump_struct(mem_ctx, pinfo_gums_privilege, p, ptr, indent); } -int gen_parse_struct_tdbsam2_priv_data(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_tdbsam2_priv_data, ptr, str); +int gen_parse_struct_gums_privilege(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { + return gen_parse_struct(mem_ctx, pinfo_gums_privilege, ptr, str); } diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 8fbd8d4cdc..52dee801ad 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -79,7 +79,7 @@ void pdb_fill_default_sam(SAM_ACCOUNT *user) user->private.logoff_time = user->private.kickoff_time = user->private.pass_must_change_time = get_time_t_max(); - user->private.unknown_3 = 0x00ffffff; /* don't know */ + user->private.fields_present = 0x00ffffff; /* don't know */ user->private.logon_divs = 168; /* hours per week */ user->private.hours_len = 21; /* 21 times 8 bits = 168 */ memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */ @@ -1346,7 +1346,7 @@ BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) fullname_len, homedir_len, logon_script_len, profile_path_len, acct_desc_len, workstations_len; - uint32 user_rid, group_rid, unknown_3, hours_len, unknown_6; + uint32 user_rid, group_rid, remove_me, hours_len, unknown_6; uint16 acct_ctrl, logon_divs; uint16 bad_password_count, logon_count; uint8 *hours; @@ -1385,7 +1385,7 @@ BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) &lm_pw_len, &lm_pw_ptr, &nt_pw_len, &nt_pw_ptr, &acct_ctrl, - &unknown_3, + &remove_me, /* remove on the next TDB_FORMAT upgarde */ &logon_divs, &hours_len, &hourslen, &hours, @@ -1463,7 +1463,6 @@ BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET); - pdb_set_unknown_3(sampass, unknown_3, PDB_SET); pdb_set_hours_len(sampass, hours_len, PDB_SET); pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); pdb_set_logon_count(sampass, logon_count, PDB_SET); @@ -1667,7 +1666,7 @@ uint32 init_buffer_from_sam_v0 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si lm_pw_len, lm_pw, nt_pw_len, nt_pw, pdb_get_acct_ctrl(sampass), - pdb_get_unknown_3(sampass), + 0, /* was: fileds_present, to be removed on format change */ pdb_get_logon_divs(sampass), pdb_get_hours_len(sampass), MAX_HOURS_LEN, pdb_get_hours(sampass), @@ -1710,7 +1709,7 @@ uint32 init_buffer_from_sam_v0 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si lm_pw_len, lm_pw, nt_pw_len, nt_pw, pdb_get_acct_ctrl(sampass), - pdb_get_unknown_3(sampass), + 0, /* was: fileds_present, to be removed on format change */ pdb_get_logon_divs(sampass), pdb_get_hours_len(sampass), MAX_HOURS_LEN, pdb_get_hours(sampass), @@ -1762,7 +1761,7 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) fullname_len, homedir_len, logon_script_len, profile_path_len, acct_desc_len, workstations_len; - uint32 user_rid, group_rid, unknown_3, hours_len, unknown_6; + uint32 user_rid, group_rid, remove_me, hours_len, unknown_6; uint16 acct_ctrl, logon_divs; uint16 bad_password_count, logon_count; uint8 *hours; @@ -1802,7 +1801,7 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) &lm_pw_len, &lm_pw_ptr, &nt_pw_len, &nt_pw_ptr, &acct_ctrl, - &unknown_3, + &remove_me, &logon_divs, &hours_len, &hourslen, &hours, @@ -1880,7 +1879,6 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET); - pdb_set_unknown_3(sampass, unknown_3, PDB_SET); pdb_set_hours_len(sampass, hours_len, PDB_SET); pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); pdb_set_logon_count(sampass, logon_count, PDB_SET); @@ -2087,7 +2085,7 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si lm_pw_len, lm_pw, nt_pw_len, nt_pw, pdb_get_acct_ctrl(sampass), - pdb_get_unknown_3(sampass), + 0, pdb_get_logon_divs(sampass), pdb_get_hours_len(sampass), MAX_HOURS_LEN, pdb_get_hours(sampass), @@ -2131,7 +2129,7 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si lm_pw_len, lm_pw, nt_pw_len, nt_pw, pdb_get_acct_ctrl(sampass), - pdb_get_unknown_3(sampass), + 0, pdb_get_logon_divs(sampass), pdb_get_hours_len(sampass), MAX_HOURS_LEN, pdb_get_hours(sampass), diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 4a5a5759d4..11df0ad56d 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -306,14 +306,6 @@ const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass) return (NULL); } -uint32 pdb_get_unknown_3 (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.unknown_3); - else - return (-1); -} - uint16 pdb_get_bad_password_count(const SAM_ACCOUNT *sampass) { if (sampass) @@ -982,16 +974,6 @@ BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag); } -BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.unknown_3 = unkn; - - return pdb_set_init_flags(sampass, PDB_UNKNOWN3, flag); -} - BOOL pdb_set_bad_password_count(SAM_ACCOUNT *sampass, uint16 bad_password_count, enum pdb_value_state flag) { if (!sampass) @@ -1128,3 +1110,11 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext) return True; } + +/* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */ +uint32 pdb_build_fields_present (SAM_ACCOUNT *sampass) +{ + /* value set to all for testing */ + return 0x00ffffff; +} + diff --git a/source3/passdb/pdb_gums.c b/source3/passdb/pdb_gums.c index 25dc565253..c595a51e55 100644 --- a/source3/passdb/pdb_gums.c +++ b/source3/passdb/pdb_gums.c @@ -1,7 +1,12 @@ /* +<<<<<<< pdb_gums.c + * 'Gums' password backend for samba + * Copyright (C) Simo Sorce 2003 +======= * GUMS password backend for samba * Copyright (C) Jelmer Vernooij 2002 * Copyright (C) Andrew Bartlett 2003 +>>>>>>> 1.4 * * 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 the Free @@ -95,7 +100,6 @@ static NTSTATUS gums_object_to_sam_account(SAM_ACCOUNT *sa, GUMS_OBJECT *go) } data_blob_clear_free(&pwd); - BOOL_SET_OR_FAIL(pdb_set_unknown_3(sa, gums_get_user_unknown_3(go), PDB_SET), error); BOOL_SET_OR_FAIL(pdb_set_bad_password_count(sa, gums_get_user_bad_password_count(go), PDB_SET), error); BOOL_SET_OR_FAIL(pdb_set_unknown_6(sa, gums_get_user_unknown_6(go), PDB_SET), error); BOOL_SET_OR_FAIL(pdb_set_hours(sa, gums_get_user_hours(go), PDB_SET), error); @@ -155,7 +159,6 @@ static NTSTATUS sam_account_to_gums_object(GUMS_OBJECT *go, SAM_ACCOUNT *sa) SET_OR_FAIL(gums_set_user_logon_divs(go, pdb_get_logon_divs(sa)), error); if (pdb_get_hours(sa)) SET_OR_FAIL(gums_set_user_hours(go, pdb_get_hours_len(sa), pdb_get_hours(sa)), error); - SET_OR_FAIL(gums_set_user_unknown_3(go, pdb_get_unknown_3(sa)), error); SET_OR_FAIL(gums_set_user_bad_password_count(go, pdb_get_bad_password_count(sa)), error); SET_OR_FAIL(gums_set_user_unknown_6(go, pdb_get_unknown_6(sa)), error); diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 6e8ff83507..ff2b5cf762 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -712,8 +712,6 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, /* pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */ - /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */ - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) { /* leave as default */ diff --git a/source3/passdb/pdb_mysql.c b/source3/passdb/pdb_mysql.c index acc1eff829..deed27dbe4 100644 --- a/source3/passdb/pdb_mysql.c +++ b/source3/passdb/pdb_mysql.c @@ -111,7 +111,6 @@ static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u) pdb_set_plaintext_passwd(u, row[22]); pdb_set_acct_ctrl(u, xatol(row[23]), PDB_SET); - pdb_set_unknown_3(u, xatol(row[24]), PDB_SET); pdb_set_logon_divs(u, xatol(row[25]), PDB_SET); pdb_set_hours_len(u, xatol(row[26]), PDB_SET); pdb_set_bad_password_count(u, xatol(row[27]), PDB_SET); diff --git a/source3/passdb/pdb_pgsql.c b/source3/passdb/pdb_pgsql.c index 61c620e092..1731c720a2 100644 --- a/source3/passdb/pdb_pgsql.c +++ b/source3/passdb/pdb_pgsql.c @@ -98,7 +98,6 @@ static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u ) pdb_set_munged_dial ( u, PQgetvalue( r, row, 17 ), PDB_SET ) ; pdb_set_acct_ctrl ( u, PQgetlong ( r, row, 23 ), PDB_SET ) ; - pdb_set_unknown_3 ( u, PQgetlong ( r, row, 24 ), PDB_SET ) ; pdb_set_logon_divs ( u, PQgetlong ( r, row, 25 ), PDB_SET ) ; pdb_set_hours_len ( u, PQgetlong ( r, row, 26 ), PDB_SET ) ; pdb_set_logon_count ( u, PQgetlong ( r, row, 27 ), PDB_SET ) ; diff --git a/source3/passdb/pdb_sql.c b/source3/passdb/pdb_sql.c index b87004e019..d3e8b90a85 100644 --- a/source3/passdb/pdb_sql.c +++ b/source3/passdb/pdb_sql.c @@ -44,7 +44,6 @@ #define CONFIG_NT_PW_DEFAULT "nt_pw" #define CONFIG_PLAIN_PW_DEFAULT "NULL" #define CONFIG_ACCT_CTRL_DEFAULT "acct_ctrl" -#define CONFIG_UNKNOWN_3_DEFAULT "unknown_3" #define CONFIG_LOGON_DIVS_DEFAULT "logon_divs" #define CONFIG_HOURS_LEN_DEFAULT "hours_len" #define CONFIG_BAD_PASSWORD_COUNT_DEFAULT "bad_password_count" @@ -254,8 +253,6 @@ char *sql_account_query_select(const char *data, BOOL update, enum sql_search_fi CONFIG_PLAIN_PW_DEFAULT), config_value_read(data, "acct ctrl column", CONFIG_ACCT_CTRL_DEFAULT), - config_value_read(data, "unknown 3 column", - CONFIG_UNKNOWN_3_DEFAULT), config_value_read(data, "logon divs column", CONFIG_LOGON_DIVS_DEFAULT), config_value_read(data, "hours len column", diff --git a/source3/passdb/pdb_xml.c b/source3/passdb/pdb_xml.c index 19998a6655..2738ad40e2 100644 --- a/source3/passdb/pdb_xml.c +++ b/source3/passdb/pdb_xml.c @@ -154,11 +154,6 @@ static BOOL parseUser(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SAM_ACCOUNT * atol(xmlNodeListGetString (doc, cur->xmlChildrenNode, 1)), PDB_SET); - else if (!strcmp(cur->name, "unknown_3") && cur->ns == ns) - pdb_set_unknown_3(u, - atol(xmlNodeListGetString - (doc, cur->xmlChildrenNode, 1)), PDB_SET); - else if (!strcmp(cur->name, "bad_password_count") && cur->ns == ns) pdb_set_bad_password_count(u, atol(xmlNodeListGetString @@ -490,7 +485,6 @@ static NTSTATUS xmlsam_add_sam_account(struct pdb_methods *methods, SAM_ACCOUNT } xmlNewChild(user, data->ns, "acct_ctrl", iota(pdb_get_acct_ctrl(u))); - xmlNewChild(user, data->ns, "unknown_3", iota(pdb_get_unknown_3(u))); if (pdb_get_logon_divs(u)) xmlNewChild(user, data->ns, "logon_divs", diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 607c9ecf64..e0eb2958b3 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -5315,11 +5315,6 @@ static BOOL sam_io_user_info11(const char *desc, SAM_USER_INFO_11 * usr, /************************************************************************* init_sam_user_infoa - - unknown_3 = 0x09f8 27fa - unknown_5 = 0x0001 0000 - unknown_6 = 0x0000 04ec - *************************************************************************/ void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516], uint16 pw_len) @@ -5362,7 +5357,6 @@ static BOOL sam_io_user_info24(const char *desc, SAM_USER_INFO_24 * usr, /************************************************************************* init_sam_user_info23 - unknown_3 = 0x09f8 27fa unknown_6 = 0x0000 04ec *************************************************************************/ @@ -5386,7 +5380,7 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z uint32 user_rid, /* 0x0000 0000 */ uint32 group_rid, uint32 acb_info, - uint32 unknown_3, + uint32 fields_present, uint16 logon_divs, LOGON_HRS * hrs, uint16 bad_password_count, @@ -5406,7 +5400,7 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z usr->user_rid = user_rid; /* 0x0000 0000 */ usr->group_rid = group_rid; usr->acb_info = acb_info; - usr->unknown_3 = unknown_3; /* 09f8 27fa */ + usr->fields_present = fields_present; /* 09f8 27fa */ usr->logon_divs = logon_divs; /* should be 168 (hours/week) */ usr->ptr_logon_hrs = hrs ? 1 : 0; @@ -5464,7 +5458,6 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z /************************************************************************* init_sam_user_info23 - unknown_3 = 0x09f8 27fa unknown_6 = 0x0000 04ec *************************************************************************/ @@ -5481,7 +5474,7 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z char *prof_path, const char *desc, char *wkstas, char *unk_str, char *mung_dial, uint32 user_rid, /* 0x0000 0000 */ uint32 group_rid, uint32 acb_info, - uint32 unknown_3, uint16 logon_divs, + uint32 fields_present, uint16 logon_divs, LOGON_HRS * hrs, uint16 bad_password_count, uint16 logon_count, char newpass[516], uint32 unknown_6) { @@ -5500,7 +5493,7 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z usr->user_rid = user_rid; /* 0x0000 0000 */ usr->group_rid = group_rid; usr->acb_info = acb_info; - usr->unknown_3 = unknown_3; /* 09f8 27fa */ + usr->fields_present = fields_present; /* 09f8 27fa */ usr->logon_divs = logon_divs; /* should be 168 (hours/week) */ usr->ptr_logon_hrs = hrs ? 1 : 0; @@ -5619,7 +5612,7 @@ static BOOL sam_io_user_info23(const char *desc, SAM_USER_INFO_23 * usr, if(!prs_uint32("acb_info ", ps, depth, &usr->acb_info)) return False; - if(!prs_uint32("unknown_3 ", ps, depth, &usr->unknown_3)) + if(!prs_uint32("fields_present ", ps, depth, &usr->fields_present)) return False; if(!prs_uint16("logon_divs ", ps, depth, &usr->logon_divs)) /* logon divisions per week */ return False; @@ -5816,7 +5809,6 @@ static BOOL sam_io_user_info25(const char *desc, SAM_USER_INFO_25 * usr, prs_str /************************************************************************* init_sam_user_info21W - unknown_3 = 0x00ff ffff unknown_6 = 0x0000 04ec *************************************************************************/ @@ -5843,7 +5835,7 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr, uint32 user_rid, uint32 group_rid, uint32 acb_info, - uint32 unknown_3, + uint32 fields_present, uint16 logon_divs, LOGON_HRS * hrs, uint16 bad_password_count, @@ -5863,7 +5855,7 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr, usr->user_rid = user_rid; usr->group_rid = group_rid; usr->acb_info = acb_info; - usr->unknown_3 = unknown_3; /* 0x00ff ffff */ + usr->fields_present = fields_present; /* 0x00ff ffff */ usr->logon_divs = logon_divs; /* should be 168 (hours/week) */ usr->ptr_logon_hrs = hrs ? 1 : 0; @@ -5918,7 +5910,6 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr, /************************************************************************* init_sam_user_info21 - unknown_3 = 0x00ff ffff unknown_6 = 0x0000 04ec *************************************************************************/ @@ -6003,16 +5994,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * usr->group_rid = group_rid; usr->acb_info = pdb_get_acct_ctrl(pw); - /* - Look at a user on a real NT4 PDC with usrmgr, press - 'ok'. Then you will see that unknown_3 is set to - 0x08f827fa. Look at the user immediately after that again, - and you will see that 0x00fffff is returned. This solves - the problem that you get access denied after having looked - at the user. - -- Volker - */ - usr->unknown_3 = 0x00ffffff; + usr->fields_present = pdb_build_fields_present(pw); usr->logon_divs = pdb_get_logon_divs(pw); usr->ptr_logon_hrs = pdb_get_hours(pw) ? 1 : 0; @@ -6133,7 +6115,7 @@ static BOOL sam_io_user_info21(const char *desc, SAM_USER_INFO_21 * usr, if(!prs_uint32("acb_info ", ps, depth, &usr->acb_info)) return False; - if(!prs_uint32("unknown_3 ", ps, depth, &usr->unknown_3)) + if(!prs_uint32("fields_present ", ps, depth, &usr->fields_present)) return False; if(!prs_uint16("logon_divs ", ps, depth, &usr->logon_divs)) /* logon divisions per week */ return False; diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index 82f93a5b4c..d54a858878 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -73,22 +73,24 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) if (from == NULL || to == NULL) return; - if (!nt_time_is_zero(&from->logon_time)) { + + if (from->fields_present & ACCT_LAST_LOGON) { unix_time=nt_time_to_unix(&from->logon_time); stored_time = pdb_get_logon_time(to); DEBUG(10,("INFO_21 LOGON_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); if (stored_time != unix_time) pdb_set_logon_time(to, unix_time, PDB_CHANGED); - } - if (!nt_time_is_zero(&from->logoff_time)) { + } + + if (from->fields_present & ACCT_LAST_LOGOFF) { unix_time=nt_time_to_unix(&from->logoff_time); stored_time = pdb_get_logoff_time(to); DEBUG(10,("INFO_21 LOGOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); if (stored_time != unix_time) pdb_set_logoff_time(to, unix_time, PDB_CHANGED); } - - if (!nt_time_is_zero(&from->kickoff_time)) { + + if (from->fields_present & ACCT_EXPIRY) { unix_time=nt_time_to_unix(&from->kickoff_time); stored_time = pdb_get_kickoff_time(to); DEBUG(10,("INFO_21 KICKOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); @@ -96,14 +98,15 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_kickoff_time(to, unix_time , PDB_CHANGED); } - if (!nt_time_is_zero(&from->pass_can_change_time)) { + if (from->fields_present & ACCT_ALLOW_PWD_CHANGE) { unix_time=nt_time_to_unix(&from->pass_can_change_time); stored_time = pdb_get_pass_can_change_time(to); DEBUG(10,("INFO_21 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); if (stored_time != unix_time) pdb_set_pass_can_change_time(to, unix_time, PDB_CHANGED); } - if (!nt_time_is_zero(&from->pass_last_set_time)) { + + if (from->fields_present & ACCT_LAST_PWD_CHANGE) { unix_time=nt_time_to_unix(&from->pass_last_set_time); stored_time = pdb_get_pass_last_set_time(to); DEBUG(10,("INFO_21 PASS_LAST_SET: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); @@ -111,7 +114,7 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED); } - if (!nt_time_is_zero(&from->pass_must_change_time)) { + if (from->fields_present & ACCT_FORCE_PWD_CHANGE) { unix_time=nt_time_to_unix(&from->pass_must_change_time); stored_time=pdb_get_pass_must_change_time(to); DEBUG(10,("INFO_21 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); @@ -119,8 +122,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_pass_must_change_time(to, unix_time, PDB_CHANGED); } - /* Backend should check this for sainity */ - if (from->hdr_user_name.buffer) { + if ((from->fields_present & ACCT_USERNAME) && + (from->hdr_user_name.buffer)) { old_string = pdb_get_username(to); new_string = unistr2_static(&from->uni_user_name); DEBUG(10,("INFO_21 UNI_USER_NAME: %s -> %s\n", old_string, new_string)); @@ -128,7 +131,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_username(to , new_string, PDB_CHANGED); } - if (from->hdr_full_name.buffer) { + if ((from->fields_present & ACCT_FULL_NAME) && + (from->hdr_full_name.buffer)) { old_string = pdb_get_fullname(to); new_string = unistr2_static(&from->uni_full_name); DEBUG(10,("INFO_21 UNI_FULL_NAME: %s -> %s\n",old_string, new_string)); @@ -136,7 +140,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_fullname(to , new_string, PDB_CHANGED); } - if (from->hdr_home_dir.buffer) { + if ((from->fields_present & ACCT_HOME_DIR) && + (from->hdr_home_dir.buffer)) { old_string = pdb_get_homedir(to); new_string = unistr2_static(&from->uni_home_dir); DEBUG(10,("INFO_21 UNI_HOME_DIR: %s -> %s\n",old_string,new_string)); @@ -144,7 +149,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_homedir(to , new_string, PDB_CHANGED); } - if (from->hdr_dir_drive.buffer) { + if ((from->fields_present & ACCT_HOME_DRIVE) && + (from->hdr_dir_drive.buffer)) { old_string = pdb_get_dir_drive(to); new_string = unistr2_static(&from->uni_dir_drive); DEBUG(10,("INFO_21 UNI_DIR_DRIVE: %s -> %s\n",old_string,new_string)); @@ -152,7 +158,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_dir_drive(to , new_string, PDB_CHANGED); } - if (from->hdr_logon_script.buffer) { + if ((from->fields_present & ACCT_LOGON_SCRIPT) && + (from->hdr_logon_script.buffer)) { old_string = pdb_get_logon_script(to); new_string = unistr2_static(&from->uni_logon_script); DEBUG(10,("INFO_21 UNI_LOGON_SCRIPT: %s -> %s\n",old_string,new_string)); @@ -160,7 +167,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_logon_script(to , new_string, PDB_CHANGED); } - if (from->hdr_profile_path.buffer) { + if ((from->fields_present & ACCT_PROFILE) && + (from->hdr_profile_path.buffer)) { old_string = pdb_get_profile_path(to); new_string = unistr2_static(&from->uni_profile_path); DEBUG(10,("INFO_21 UNI_PROFILE_PATH: %s -> %s\n",old_string, new_string)); @@ -168,7 +176,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_profile_path(to , new_string, PDB_CHANGED); } - if (from->hdr_acct_desc.buffer) { + if ((from->fields_present & ACCT_DESCRIPTION) && + (from->hdr_acct_desc.buffer)) { old_string = pdb_get_acct_desc(to); new_string = unistr2_static(&from->uni_acct_desc); DEBUG(10,("INFO_21 UNI_ACCT_DESC: %s -> %s\n",old_string,new_string)); @@ -176,7 +185,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_acct_desc(to , new_string, PDB_CHANGED); } - if (from->hdr_workstations.buffer) { + if ((from->fields_present & ACCT_WORKSTATIONS) && + (from->hdr_workstations.buffer)) { old_string = pdb_get_workstations(to); new_string = unistr2_static(&from->uni_workstations); DEBUG(10,("INFO_21 UNI_WORKSTATIONS: %s -> %s\n",old_string, new_string)); @@ -184,7 +194,9 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_workstations(to , new_string, PDB_CHANGED); } - if (from->hdr_unknown_str.buffer) { + /* is this right? */ + if ((from->fields_present & ACCT_ADMIN_DESC) && + (from->hdr_unknown_str.buffer)) { old_string = pdb_get_unknown_str(to); new_string = unistr2_static(&from->uni_unknown_str); DEBUG(10,("INFO_21 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string)); @@ -192,7 +204,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) pdb_set_unknown_str(to , new_string, PDB_CHANGED); } - if (from->hdr_munged_dial.buffer) { + if ((from->fields_present & ACCT_CALLBACK) && + (from->hdr_munged_dial.buffer)) { char *newstr; old_string = pdb_get_munged_dial(to); mung.length = from->hdr_munged_dial.uni_str_len; @@ -205,7 +218,8 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) SAFE_FREE(newstr); } - if (from->user_rid == 0) { + if ((from->fields_present & ACCT_RID) && + (from->user_rid == 0)) { DEBUG(10, ("INFO_21: Asked to set User RID to 0 !? Skipping change!\n")); } else if (from->user_rid != pdb_get_user_rid(to)) { DEBUG(10,("INFO_21 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid)); @@ -213,51 +227,57 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) /* pdb_set_user_sid_from_rid(to, from->user_rid, PDB_CHANGED);*/ } - if (from->group_rid == 0) { + if ((from->fields_present & ACCT_PRIMARY_GID) && + (from->group_rid == 0)) { DEBUG(10, ("INFO_21: Asked to set Group RID to 0 !? Skipping change!\n")); } else if (from->group_rid != pdb_get_group_rid(to)) { DEBUG(10,("INFO_21 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid)); pdb_set_group_sid_from_rid(to, from->group_rid, PDB_CHANGED); } - DEBUG(10,("INFO_21 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info)); - if (from->acb_info != pdb_get_acct_ctrl(to)) { - pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED); + if (from->fields_present & ACCT_FLAGS) { + DEBUG(10,("INFO_21 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info)); + if (from->acb_info != pdb_get_acct_ctrl(to)) { + pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED); + } } - DEBUG(10,("INFO_21 UNKNOWN_3: %08X -> %08X\n",pdb_get_unknown_3(to),from->unknown_3)); - if (from->unknown_3 != pdb_get_unknown_3(to)) { - pdb_set_unknown_3(to, from->unknown_3, PDB_CHANGED); - } + if (from->fields_present & ACCT_LOGON_HOURS) { + DEBUG(15,("INFO_21 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs)); + if (from->logon_divs != pdb_get_logon_divs(to)) { + pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED); + } - DEBUG(15,("INFO_21 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs)); - if (from->logon_divs != pdb_get_logon_divs(to)) { - pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED); - } + DEBUG(15,("INFO_21 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len)); + if (from->logon_hrs.len != pdb_get_hours_len(to)) { + pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED); + } - DEBUG(15,("INFO_21 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len)); - if (from->logon_hrs.len != pdb_get_hours_len(to)) { - pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED); + DEBUG(15,("INFO_21 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours)); + /* Fix me: only update if it changes --metze */ + pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED); } - DEBUG(15,("INFO_21 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours)); -/* Fix me: only update if it changes --metze */ - pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED); - - DEBUG(10,("INFO_21 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count)); - if (from->bad_password_count != pdb_get_bad_password_count(to)) { - pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED); + if (from->fields_present & ACCT_BAD_PWD_COUNT) { + DEBUG(10,("INFO_21 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count)); + if (from->bad_password_count != pdb_get_bad_password_count(to)) { + pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED); + } } - DEBUG(10,("INFO_21 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count)); - if (from->logon_count != pdb_get_logon_count(to)) { - pdb_set_logon_count(to, from->logon_count, PDB_CHANGED); + if (from->fields_present & ACCT_NUM_LOGONS) { + DEBUG(10,("INFO_21 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count)); + if (from->logon_count != pdb_get_logon_count(to)) { + pdb_set_logon_count(to, from->logon_count, PDB_CHANGED); + } } - DEBUG(10,("INFO_21 UNKNOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6)); - if (from->unknown_6 != pdb_get_unknown_6(to)) { - pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED); - } + /* if (from->fields_present & ACCT_??) { */ + DEBUG(10,("INFO_21 UNKNOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6)); + if (from->unknown_6 != pdb_get_unknown_6(to)) { + pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED); + } + /* } */ DEBUG(10,("INFO_21 PADDING1 %02X %02X %02X %02X %02X %02X\n", from->padding1[0], @@ -269,7 +289,25 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) DEBUG(10,("INFO_21 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange)); if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) { - pdb_set_pass_must_change_time(to,0, PDB_CHANGED); + pdb_set_pass_must_change_time(to,0, PDB_CHANGED); + } else { + uint32 expire; + time_t new_time; + if (pdb_get_pass_must_change_time(to) == 0) { + if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire) + || expire == (uint32)-1) { + new_time = get_time_t_max(); + } else { + time_t old_time = pdb_get_pass_last_set_time(to); + new_time = old_time + expire; + if ((new_time) < time(0)) { + new_time = time(0) + expire; + } + } + if (!pdb_set_pass_must_change_time (to, new_time, PDB_CHANGED)) { + DEBUG (0, ("pdb_set_pass_must_change_time failed!\n")); + } + } } DEBUG(10,("INFO_21 PADDING_2: %02X\n",from->padding2)); @@ -290,14 +328,16 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) if (from == NULL || to == NULL) return; - if (!nt_time_is_zero(&from->logon_time)) { + + if (from->fields_present & ACCT_LAST_LOGON) { unix_time=nt_time_to_unix(&from->logon_time); stored_time = pdb_get_logon_time(to); DEBUG(10,("INFO_23 LOGON_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); if (stored_time != unix_time) pdb_set_logon_time(to, unix_time, PDB_CHANGED); - } - if (!nt_time_is_zero(&from->logoff_time)) { + } + + if (from->fields_present & ACCT_LAST_LOGOFF) { unix_time=nt_time_to_unix(&from->logoff_time); stored_time = pdb_get_logoff_time(to); DEBUG(10,("INFO_23 LOGOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); @@ -305,7 +345,7 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_logoff_time(to, unix_time, PDB_CHANGED); } - if (!nt_time_is_zero(&from->kickoff_time)) { + if (from->fields_present & ACCT_EXPIRY) { unix_time=nt_time_to_unix(&from->kickoff_time); stored_time = pdb_get_kickoff_time(to); DEBUG(10,("INFO_23 KICKOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); @@ -313,14 +353,15 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_kickoff_time(to, unix_time , PDB_CHANGED); } - if (!nt_time_is_zero(&from->pass_can_change_time)) { + if (from->fields_present & ACCT_ALLOW_PWD_CHANGE) { unix_time=nt_time_to_unix(&from->pass_can_change_time); stored_time = pdb_get_pass_can_change_time(to); DEBUG(10,("INFO_23 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); if (stored_time != unix_time) pdb_set_pass_can_change_time(to, unix_time, PDB_CHANGED); } - if (!nt_time_is_zero(&from->pass_last_set_time)) { + + if (from->fields_present & ACCT_LAST_PWD_CHANGE) { unix_time=nt_time_to_unix(&from->pass_last_set_time); stored_time = pdb_get_pass_last_set_time(to); DEBUG(10,("INFO_23 PASS_LAST_SET: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); @@ -328,7 +369,7 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED); } - if (!nt_time_is_zero(&from->pass_must_change_time)) { + if (from->fields_present & ACCT_FORCE_PWD_CHANGE) { unix_time=nt_time_to_unix(&from->pass_must_change_time); stored_time=pdb_get_pass_must_change_time(to); DEBUG(10,("INFO_23 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time)); @@ -336,8 +377,9 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_pass_must_change_time(to, unix_time, PDB_CHANGED); } - /* Backend should check this for sainity */ - if (from->hdr_user_name.buffer) { + /* Backend should check this for sanity */ + if ((from->fields_present & ACCT_USERNAME) && + (from->hdr_user_name.buffer)) { old_string = pdb_get_username(to); new_string = unistr2_static(&from->uni_user_name); DEBUG(10,("INFO_23 UNI_USER_NAME: %s -> %s\n", old_string, new_string)); @@ -345,7 +387,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_username(to , new_string, PDB_CHANGED); } - if (from->hdr_full_name.buffer) { + if ((from->fields_present & ACCT_FULL_NAME) && + (from->hdr_full_name.buffer)) { old_string = pdb_get_fullname(to); new_string = unistr2_static(&from->uni_full_name); DEBUG(10,("INFO_23 UNI_FULL_NAME: %s -> %s\n",old_string, new_string)); @@ -353,7 +396,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_fullname(to , new_string, PDB_CHANGED); } - if (from->hdr_home_dir.buffer) { + if ((from->fields_present & ACCT_HOME_DIR) && + (from->hdr_home_dir.buffer)) { old_string = pdb_get_homedir(to); new_string = unistr2_static(&from->uni_home_dir); DEBUG(10,("INFO_23 UNI_HOME_DIR: %s -> %s\n",old_string,new_string)); @@ -361,7 +405,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_homedir(to , new_string, PDB_CHANGED); } - if (from->hdr_dir_drive.buffer) { + if ((from->fields_present & ACCT_HOME_DRIVE) && + (from->hdr_dir_drive.buffer)) { old_string = pdb_get_dir_drive(to); new_string = unistr2_static(&from->uni_dir_drive); DEBUG(10,("INFO_23 UNI_DIR_DRIVE: %s -> %s\n",old_string,new_string)); @@ -369,7 +414,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_dir_drive(to , new_string, PDB_CHANGED); } - if (from->hdr_logon_script.buffer) { + if ((from->fields_present & ACCT_LOGON_SCRIPT) && + (from->hdr_logon_script.buffer)) { old_string = pdb_get_logon_script(to); new_string = unistr2_static(&from->uni_logon_script); DEBUG(10,("INFO_23 UNI_LOGON_SCRIPT: %s -> %s\n",old_string,new_string)); @@ -377,7 +423,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_logon_script(to , new_string, PDB_CHANGED); } - if (from->hdr_profile_path.buffer) { + if ((from->fields_present & ACCT_PROFILE) && + (from->hdr_profile_path.buffer)) { old_string = pdb_get_profile_path(to); new_string = unistr2_static(&from->uni_profile_path); DEBUG(10,("INFO_23 UNI_PROFILE_PATH: %s -> %s\n",old_string, new_string)); @@ -385,7 +432,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_profile_path(to , new_string, PDB_CHANGED); } - if (from->hdr_acct_desc.buffer) { + if ((from->fields_present & ACCT_DESCRIPTION) && + (from->hdr_acct_desc.buffer)) { old_string = pdb_get_acct_desc(to); new_string = unistr2_static(&from->uni_acct_desc); DEBUG(10,("INFO_23 UNI_ACCT_DESC: %s -> %s\n",old_string,new_string)); @@ -393,7 +441,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_acct_desc(to , new_string, PDB_CHANGED); } - if (from->hdr_workstations.buffer) { + if ((from->fields_present & ACCT_WORKSTATIONS) && + (from->hdr_workstations.buffer)) { old_string = pdb_get_workstations(to); new_string = unistr2_static(&from->uni_workstations); DEBUG(10,("INFO_23 UNI_WORKSTATIONS: %s -> %s\n",old_string, new_string)); @@ -401,7 +450,9 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_workstations(to , new_string, PDB_CHANGED); } - if (from->hdr_unknown_str.buffer) { + /* is this right? */ + if ((from->fields_present & ACCT_ADMIN_DESC) && + (from->hdr_unknown_str.buffer)) { old_string = pdb_get_unknown_str(to); new_string = unistr2_static(&from->uni_unknown_str); DEBUG(10,("INFO_23 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string)); @@ -409,7 +460,8 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) pdb_set_unknown_str(to , new_string, PDB_CHANGED); } - if (from->hdr_munged_dial.buffer) { + if ((from->fields_present & ACCT_CALLBACK) && + (from->hdr_munged_dial.buffer)) { char *newstr; old_string = pdb_get_munged_dial(to); mung.length = from->hdr_munged_dial.uni_str_len; @@ -422,58 +474,66 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) SAFE_FREE(newstr); } - if (from->user_rid == 0) { + if ((from->fields_present & ACCT_RID) && + (from->user_rid == 0)) { DEBUG(10, ("INFO_23: Asked to set User RID to 0 !? Skipping change!\n")); } else if (from->user_rid != pdb_get_user_rid(to)) { DEBUG(10,("INFO_23 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid)); /* we really allow this ??? metze */ /* pdb_set_user_sid_from_rid(to, from->user_rid, PDB_CHANGED);*/ } - if (from->group_rid == 0) { + + if ((from->fields_present & ACCT_PRIMARY_GID) && + (from->group_rid == 0)) { DEBUG(10, ("INFO_23: Asked to set Group RID to 0 !? Skipping change!\n")); } else if (from->group_rid != pdb_get_group_rid(to)) { DEBUG(10,("INFO_23 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid)); pdb_set_group_sid_from_rid(to, from->group_rid, PDB_CHANGED); } - DEBUG(10,("INFO_23 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info)); - if (from->acb_info != pdb_get_acct_ctrl(to)) { - pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED); + if (from->fields_present & ACCT_FLAGS) { + DEBUG(10,("INFO_23 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info)); + if (from->acb_info != pdb_get_acct_ctrl(to)) { + pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED); + } } - DEBUG(10,("INFO_23 UNKOWN_3: %08X -> %08X\n",pdb_get_unknown_3(to),from->unknown_3)); - if (from->unknown_3 != pdb_get_unknown_3(to)) { - pdb_set_unknown_3(to, from->unknown_3, PDB_CHANGED); - } + if (from->fields_present & ACCT_LOGON_HOURS) { + DEBUG(15,("INFO_23 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs)); + if (from->logon_divs != pdb_get_logon_divs(to)) { + pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED); + } - DEBUG(15,("INFO_23 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs)); - if (from->logon_divs != pdb_get_logon_divs(to)) { - pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED); - } + DEBUG(15,("INFO_23 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len)); + if (from->logon_hrs.len != pdb_get_hours_len(to)) { + pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED); + } - DEBUG(15,("INFO_23 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len)); - if (from->logon_hrs.len != pdb_get_hours_len(to)) { - pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED); + DEBUG(15,("INFO_23 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours)); + /* Fix me: only update if it changes --metze */ + pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED); } - DEBUG(15,("INFO_23 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours)); -/* Fix me: only update if it changes --metze */ - pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED); - - DEBUG(10,("INFO_23 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count)); - if (from->bad_password_count != pdb_get_bad_password_count(to)) { - pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED); + if (from->fields_present & ACCT_BAD_PWD_COUNT) { + DEBUG(10,("INFO_23 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count)); + if (from->bad_password_count != pdb_get_bad_password_count(to)) { + pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED); + } } - DEBUG(10,("INFO_23 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count)); - if (from->logon_count != pdb_get_logon_count(to)) { - pdb_set_logon_count(to, from->logon_count, PDB_CHANGED); + if (from->fields_present & ACCT_NUM_LOGONS) { + DEBUG(10,("INFO_23 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count)); + if (from->logon_count != pdb_get_logon_count(to)) { + pdb_set_logon_count(to, from->logon_count, PDB_CHANGED); + } } - DEBUG(10,("INFO_23 UNKOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6)); - if (from->unknown_6 != pdb_get_unknown_6(to)) { - pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED); - } + /* if (from->fields_present & ACCT_??) { */ + DEBUG(10,("INFO_23 UNKOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6)); + if (from->unknown_6 != pdb_get_unknown_6(to)) { + pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED); + } + /* } */ DEBUG(10,("INFO_23 PADDING1 %02X %02X %02X %02X %02X %02X\n", from->padding1[0], @@ -486,6 +546,24 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) DEBUG(10,("INFO_23 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange)); if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) { pdb_set_pass_must_change_time(to,0, PDB_CHANGED); + } else { + uint32 expire; + time_t new_time; + if (pdb_get_pass_must_change_time(to) == 0) { + if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire) + || expire == (uint32)-1) { + new_time = get_time_t_max(); + } else { + time_t old_time = pdb_get_pass_last_set_time(to); + new_time = old_time + expire; + if ((new_time) < time(0)) { + new_time = time(0) + expire; + } + } + if (!pdb_set_pass_must_change_time (to, new_time, PDB_CHANGED)) { + DEBUG (0, ("pdb_set_pass_must_change_time failed!\n")); + } + } } DEBUG(10,("INFO_23 PADDING_2: %02X\n",from->padding2)); diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 34c6fc35ab..455e5a89fc 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -83,7 +83,7 @@ static void display_sam_user_info_21(SAM_USER_INFO_21 *usr) printf("\tgroup_rid:\t0x%x\n" , usr->group_rid); /* Group ID */ printf("\tacb_info :\t0x%04x\n", usr->acb_info ); /* Account Control Info */ - printf("\tunknown_3:\t0x%08x\n", usr->unknown_3); /* 0x00ff ffff */ + printf("\tfileds_present:\t0x%08x\n", usr->fields_present); /* 0x00ff ffff */ printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */ printf("\tbad_password_count:\t0x%08x\n", usr->bad_password_count); printf("\tlogon_count:\t0x%08x\n", usr->logon_count); diff --git a/source3/sam/gums_api.c b/source3/sam/gums_api.c index 17f7d33baa..a76aed18fd 100644 --- a/source3/sam/gums_api.c +++ b/source3/sam/gums_api.c @@ -474,14 +474,6 @@ const uint8 *gums_get_user_hours(const GUMS_OBJECT *obj) return obj->data.user->hours; } -uint32 gums_get_user_unknown_3(const GUMS_OBJECT *obj) -{ - if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) - return 0; - - return obj->data.user->unknown_3; -} - uint16 gums_get_user_bad_password_count(const GUMS_OBJECT *obj) { if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) @@ -780,18 +772,6 @@ NTSTATUS gums_set_user_hours(GUMS_OBJECT *obj, uint32 hours_len, const uint8 *ho return NT_STATUS_OK; } -NTSTATUS gums_set_user_unknown_3(GUMS_OBJECT *obj, uint32 unknown_3) -{ - if (!obj) - return NT_STATUS_INVALID_PARAMETER; - - if (obj->type != GUMS_OBJ_NORMAL_USER) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->data.user->unknown_3 = unknown_3; - return NT_STATUS_OK; -} - NTSTATUS gums_set_user_bad_password_count(GUMS_OBJECT *obj, uint16 bad_password_count) { if (!obj) diff --git a/source3/sam/gums_helper.c b/source3/sam/gums_helper.c index 5bbd054be1..fcb9366cda 100644 --- a/source3/sam/gums_helper.c +++ b/source3/sam/gums_helper.c @@ -211,7 +211,7 @@ NTSTATUS gums_make_alias(DOM_SID *sid, const char *name, const char *description return ret; } -NTSTATUS gums_init_domain(DOM_SID *sid, const char *name) +NTSTATUS gums_init_domain(DOM_SID *sid, const char *name, const char * description) { NTSTATUS ret; @@ -219,7 +219,7 @@ NTSTATUS gums_init_domain(DOM_SID *sid, const char *name) if (!NT_STATUS_IS_OK(ret = gums_make_domain( sid, name, - NULL + description ))) { return ret; } @@ -331,7 +331,7 @@ NTSTATUS gums_init_builtin_domain(void) if (!NT_STATUS_IS_OK(ret = gums_make_alias( &global_sid_Builtin_Backup_Operators, "Backup Operators", - "Members can bypass file security to backup files" + "Members can bypass file security to backup files" ))) { return ret; } diff --git a/source3/sam/gums_tdbsam2.c b/source3/sam/gums_tdbsam2.c index 217cf6f34e..7fb9a1a997 100644 --- a/source3/sam/gums_tdbsam2.c +++ b/source3/sam/gums_tdbsam2.c @@ -19,7 +19,6 @@ */ #include "includes.h" -#include "tdbsam2.h" #include "tdbsam2_parse_info.h" #if 0 @@ -36,7 +35,9 @@ static int gums_tdbsam2_debug_class = DBGC_ALL; #define SIDPREFIX "SID_" #define PRIVILEGEPREFIX "PRIV_" -#define TDB_FORMAT_STRING "ddB" +#define TDB_BASIC_OBJ_STRING "ddd" +#define TDB_FORMAT_STRING "dddB" +#define TDB_PRIV_FORMAT_STRING "ddB" #define TALLOC_CHECK(ptr, err, label) do { if ((ptr) == NULL) { DEBUG(0, ("%s: Out of memory!\n", FUNCTION_MACRO)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0) #define SET_OR_FAIL(func, label) do { if (!NT_STATUS_IS_OK(func)) { DEBUG(0, ("%s: Setting gums object data failed!\n", FUNCTION_MACRO)); goto label; } } while(0) @@ -51,19 +52,6 @@ struct tdbsam2_enum_objs { struct tdbsam2_enum_objs *next; }; -union tdbsam2_data { - struct tdbsam2_domain_data *domain; - struct tdbsam2_user_data *user; - struct tdbsam2_group_data *group; - struct tdbsam2_priv_data *priv; -}; - -struct tdbsam2_object { - uint32 type; - uint32 version; - union tdbsam2_data data; -}; - struct tdbsam2_private_data { const char *storage; @@ -72,7 +60,6 @@ struct tdbsam2_private_data { static struct tdbsam2_private_data *ts2_privs; - static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size) { @@ -81,7 +68,7 @@ static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size int iret; char *obj_data = NULL; int data_size = 0; - int version, type; + int version, type, seqnum; int len; mem_ctx = talloc_init("init_object_from_buffer"); @@ -93,16 +80,17 @@ static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size len = tdb_unpack (buffer, size, TDB_FORMAT_STRING, &version, &type, + &seqnum, &data_size, &obj_data); if (len == -1 || data_size <= 0) goto done; - /* version is checked inside this function so that backward compatibility code can be - called eventually. - this way we can easily handle database format upgrades */ + /* version is checked inside this function so that backward + compatibility code can be called eventually. + This way we can easily handle database format upgrades */ if (version != TDBSAM_VERSION) { - DEBUG(3,("init_tdbsam2_object_from_buffer: Error, db object has wrong tdbsam version!\n")); + DEBUG(3,("init_object_from_buffer: Error, db object has wrong tdbsam version!\n")); goto done; } @@ -116,20 +104,16 @@ static NTSTATUS init_object_from_buffer(GUMS_OBJECT **go, char *buffer, int size switch (type) { case GUMS_OBJ_DOMAIN: - iret = gen_parse(mem_ctx, pinfo_tdbsam2_domain_data, (char *)(*go), obj_data); + iret = gen_parse(mem_ctx, pinfo_gums_domain, (char *)(*go), obj_data); break; case GUMS_OBJ_GROUP: case GUMS_OBJ_ALIAS: - iret = gen_parse(mem_ctx, pinfo_tdbsam2_group_data, (char *)(*go), obj_data); + iret = gen_parse(mem_ctx, pinfo_gums_group, (char *)(*go), obj_data); break; case GUMS_OBJ_NORMAL_USER: - iret = gen_parse(mem_ctx, pinfo_tdbsam2_user_data, (char *)(*go), obj_data); - break; - - case GUMS_OBJ_PRIVILEGE: - iret = gen_parse(mem_ctx, pinfo_tdbsam2_priv_data, (char *)(*go), obj_data); + iret = gen_parse(mem_ctx, pinfo_gums_user, (char *)(*go), obj_data); break; default: @@ -151,6 +135,62 @@ done: return ret; } +static NTSTATUS init_privilege_from_buffer(GUMS_PRIVILEGE **priv, char *buffer, int size) +{ + + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + TALLOC_CTX *mem_ctx; + int iret; + char *obj_data = NULL; + int data_size = 0; + int version, seqnum; + int len; + + mem_ctx = talloc_init("init_privilege_from_buffer"); + if (!mem_ctx) { + DEBUG(0, ("init_privilege_from_buffer: Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } + + len = tdb_unpack (buffer, size, TDB_PRIV_FORMAT_STRING, + &version, + &seqnum, + &data_size, &obj_data); + + if (len == -1 || data_size <= 0) + goto done; + + /* version is checked inside this function so that backward + compatibility code can be called eventually. + This way we can easily handle database format upgrades */ + if (version != TDBSAM_VERSION) { + DEBUG(3,("init_privilege_from_buffer: Error, db object has wrong tdbsam version!\n")); + goto done; + } + + /* be sure the string is terminated before trying to parse it */ + if (obj_data[data_size - 1] != '\0') + obj_data[data_size - 1] = '\0'; + + *priv = (GUMS_PRIVILEGE *)talloc_zero(mem_ctx, sizeof(GUMS_PRIVILEGE)); + TALLOC_CHECK(*priv, ret, done); + + iret = gen_parse(mem_ctx, pinfo_gums_privilege, (char *)(*priv), obj_data); + + if (iret != 0) { + DEBUG(0, ("init_privilege_from_buffer: Fatal Error! Unable to parse object!\n")); + DEBUG(0, ("init_privilege_from_buffer: DB Corrupt ?")); + goto done; + } + + (*priv)->mem_ctx = mem_ctx; + + ret = NT_STATUS_OK; +done: + SAFE_FREE(obj_data); + return ret; +} + static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX *mem_ctx, GUMS_OBJECT *object) { @@ -164,20 +204,16 @@ static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX * switch (gums_get_object_type(object)) { case GUMS_OBJ_DOMAIN: - genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_domain_data, (char *)object, 0); + genbuf = gen_dump(mem_ctx, pinfo_gums_domain, (char *)object, 0); break; case GUMS_OBJ_GROUP: case GUMS_OBJ_ALIAS: - genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_group_data, (char *)object, 0); + genbuf = gen_dump(mem_ctx, pinfo_gums_group, (char *)object, 0); break; case GUMS_OBJ_NORMAL_USER: - genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_user_data, (char *)object, 0); - break; - - case GUMS_OBJ_PRIVILEGE: - genbuf = gen_dump(mem_ctx, pinfo_tdbsam2_priv_data, (char *)object, 0); + genbuf = gen_dump(mem_ctx, pinfo_gums_user, (char *)object, 0); break; default: @@ -193,6 +229,7 @@ static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX * buflen = tdb_pack(NULL, 0, TDB_FORMAT_STRING, TDBSAM_VERSION, object->type, + object->seq_num, strlen(genbuf) + 1, genbuf); *buffer = talloc(mem_ctx, buflen); @@ -201,6 +238,7 @@ static NTSTATUS init_buffer_from_object(char **buffer, size_t *len, TALLOC_CTX * *len = tdb_pack(*buffer, buflen, TDB_FORMAT_STRING, TDBSAM_VERSION, object->type, + object->seq_num, strlen(genbuf) + 1, genbuf); if (*len != buflen) { @@ -216,6 +254,49 @@ done: return ret; } +static NTSTATUS init_buffer_from_privilege(char **buffer, size_t *len, TALLOC_CTX *mem_ctx, GUMS_PRIVILEGE *priv) +{ + + NTSTATUS ret; + char *genbuf = NULL; + size_t buflen; + + if (!buffer || !len || !mem_ctx || !priv) + return NT_STATUS_INVALID_PARAMETER; + + genbuf = gen_dump(mem_ctx, pinfo_gums_privilege, (char *)priv, 0); + + if (genbuf == NULL) { + DEBUG(0, ("init_buffer_from_privilege: Fatal Error! Unable to dump object!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + buflen = tdb_pack(NULL, 0, TDB_PRIV_FORMAT_STRING, + TDBSAM_VERSION, + priv->seq_num, + strlen(genbuf) + 1, genbuf); + + *buffer = talloc(mem_ctx, buflen); + TALLOC_CHECK(*buffer, ret, done); + + *len = tdb_pack(*buffer, buflen, TDB_PRIV_FORMAT_STRING, + TDBSAM_VERSION, + priv->seq_num, + strlen(genbuf) + 1, genbuf); + + if (*len != buflen) { + DEBUG(0, ("init_buffer_from_privilege: something odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n", + buflen, *len)); + *buffer = NULL; + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + ret = NT_STATUS_OK; +done: + return ret; +} + static NTSTATUS opentdb(TDB_CONTEXT **tdb, BOOL readonly) { if (!tdb) @@ -266,7 +347,46 @@ done: return ret; } -static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const char* name) +static NTSTATUS make_full_object_name(TDB_CONTEXT *tdb, fstring objname, GUMS_OBJECT *object) +{ + NTSTATUS ret; + + objname[0] = '\0'; + + if (gums_get_object_type(object) == GUMS_OBJ_DOMAIN) { + + fstrcpy(objname, gums_get_object_name(object)); + + } else { + GUMS_OBJECT *domain_object; + DOM_SID domain_sid; + uint32 *discard_rid; + + sid_copy(&domain_sid, gums_get_object_sid(object)); + sid_split_rid(&domain_sid, discard_rid); + + if (!NT_STATUS_IS_OK(get_object_by_sid(tdb, + &domain_object, + &domain_sid))) { + + DEBUG(3, ("Object's domain not found!\n")); + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + fstrcpy(objname, gums_get_object_name(domain_object)); + fstrcat(objname, "\\"); + fstrcat(objname, gums_get_object_name(object)); + } + + ret = NT_STATUS_OK; + +done: + return ret; +} + +/* name should be in DOMAIN\NAME format */ +static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const char *fullname) { NTSTATUS ret = NT_STATUS_OK; @@ -277,14 +397,15 @@ static NTSTATUS get_object_by_name(TDB_CONTEXT *tdb, GUMS_OBJECT **obj, const ch fstring sidstr; int sidstr_len; - if (!obj || !name) + if (!obj || !fullname) return NT_STATUS_INVALID_PARAMETER; /* Data is stored in all lower-case */ - fstrcpy(objname, name); + fstrcpy(objname, fullname); strlower_m(objname); slprintf(keystr, sizeof(keystr)-1, "%s%s", NAMEPREFIX, objname); + key.dptr = keystr; key.dsize = strlen(keystr) + 1; @@ -320,13 +441,52 @@ done: return ret; } -/* store a tdbsam2_object +/* Get object's sequence number */ + +static NTSTATUS get_object_seq_num(TDB_CONTEXT *tdb, GUMS_OBJECT *object, int *seq_num) +{ + + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + TDB_DATA data, key; + fstring keystr; + fstring sidstr; + int version, type, seqnum; + + if (!object || !seq_num) + return NT_STATUS_INVALID_PARAMETER; + + fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object))); + slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sidstr); + + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; + + data = tdb_fetch(tdb, key); + if (!data.dptr) { + DEBUG(5, ("get_object_seq_num: Entry not found!\n")); + DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdb))); + DEBUGADD(5, (" Key: %s\n", keystr)); + ret = NT_STATUS_NOT_FOUND; + goto done; + } + + if (tdb_unpack (data.dptr, data.dsize, TDB_BASIC_OBJ_STRING, &version, &type, &seqnum) == -1) + goto done; + + *seq_num = seqnum; + ret = NT_STATUS_OK; + +done: + SAFE_FREE(data.dptr); + return ret; +} + +/* store a gums object * flag: TDB_REPLACE or TDB_MODIFY or TDB_INSERT */ -static NTSTATUS store_object(TDB_CONTEXT *tdb, const GUMS_OBJECT *object, int flag) +static NTSTATUS store_object(TDB_CONTEXT *tdb, GUMS_OBJECT *object, int flag) { - NTSTATUS ret = NT_STATUS_OK; TDB_DATA data, data2, key, key2; TALLOC_CTX *mem_ctx; @@ -346,308 +506,65 @@ static NTSTATUS store_object(TDB_CONTEXT *tdb, const GUMS_OBJECT *object, int fl return NT_STATUS_NO_MEMORY; } - if (!NT_STATUS_IS_OK(ret = init_buffer_from_object(&(data.dptr), &(data.dsize), mem_ctx, object))) - goto done; - - switch (object->type) { - - case GUMS_OBJ_DOMAIN: - case GUMS_OBJ_GROUP: - case GUMS_OBJ_ALIAS: - case GUMS_OBJ_NORMAL_USER: - - fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object))); - slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sidstr); - break; - - default: - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } + make_full_object_name(tdb, objname, object); /* Data is stored in all lower-case */ - fstrcpy(objname, gums_get_object_name(object)); strlower_m(objname); - slprintf(namestr, sizeof(namestr) - 1, "%s%s", NAMEPREFIX, objname); - - if (object->type != GUMS_OBJ_PRIVILEGE) { - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - - if ((r = tdb_store(tdb, key, data, flag)) != TDB_SUCCESS) { - DEBUG(0, ("store_object: Unable to modify TDBSAM!\n")); - DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb))); - DEBUGADD(0, (" occured while storing sid record (%s)\n", keystr)); - if (r == TDB_ERR_EXISTS) - ret = NT_STATUS_UNSUCCESSFUL; - else - ret = NT_STATUS_INTERNAL_DB_ERROR; - goto done; - } - - data2.dptr = sidstr; - data2.dsize = strlen(sidstr) + 1; - key2.dptr = namestr; - key2.dsize = strlen(namestr) + 1; - - if ((r = tdb_store(tdb, key2, data2, flag)) != TDB_SUCCESS) { - DEBUG(0, ("store_object: Unable to modify TDBSAM!\n")); - DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb))); - DEBUGADD(0, (" occured while storing name record (%s)\n", keystr)); - DEBUGADD(0, (" attempting rollback operation.\n")); - if ((tdb_delete(tdb, key)) != TDB_SUCCESS) { - DEBUG(0, ("store_object: Unable to rollback! Check database consitency!\n")); - } - if (r == TDB_ERR_EXISTS) - ret = NT_STATUS_UNSUCCESSFUL; - else - ret = NT_STATUS_INTERNAL_DB_ERROR; - goto done; - } - } else { - key.dptr = namestr; - key.dsize = strlen(keystr) + 1; - - if ((r = tdb_store(tdb, key, data, flag)) != TDB_SUCCESS) { - DEBUG(0, ("store_object: Unable to modify TDBSAM!\n")); - DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb))); - DEBUGADD(0, (" occured while storing sid record (%s)\n", keystr)); - if (r == TDB_ERR_EXISTS) - ret = NT_STATUS_UNSUCCESSFUL; - else - ret = NT_STATUS_INTERNAL_DB_ERROR; + if (flag == TDB_MODIFY) { + if (!NT_STATUS_IS_OK(ret = get_object_seq_num(tdb, object, &(object->seq_num)))) goto done; - } - } - -/* TODO: update the general database counter */ -/* TODO: update this entry counter too */ - -done: - talloc_destroy(mem_ctx); - return ret; -} - -#if 0 -static NTSTATUS user_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_user_data *userdata) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - DATA_BLOB pwd; - - if (!object || !userdata) { - DEBUG(0, ("tdbsam2_user_data_to_gums_object: no NULL pointers are accepted here!\n")); - return ret; - } - - /* userdata->xcounter */ - /* userdata->sec_desc */ - - SET_OR_FAIL(gums_set_object_sid(*object, userdata->user_sid), error); - SET_OR_FAIL(gums_set_object_name(*object, userdata->name), error); - - SET_OR_FAIL(gums_set_user_pri_group(*object, userdata->group_sid), error); - - if (userdata->description) - SET_OR_FAIL(gums_set_object_description(*object, userdata->description), error); - - if (userdata->full_name) - SET_OR_FAIL(gums_set_user_fullname(*object, userdata->full_name), error); - - if (userdata->home_dir) - SET_OR_FAIL(gums_set_user_homedir(*object, userdata->home_dir), error); - - if (userdata->dir_drive) - SET_OR_FAIL(gums_set_user_dir_drive(*object, userdata->dir_drive), error); - - if (userdata->logon_script) - SET_OR_FAIL(gums_set_user_logon_script(*object, userdata->logon_script), error); - - if (userdata->profile_path) - SET_OR_FAIL(gums_set_user_profile_path(*object, userdata->profile_path), error); - - if (userdata->workstations) - SET_OR_FAIL(gums_set_user_workstations(*object, userdata->workstations), error); - - if (userdata->unknown_str) - SET_OR_FAIL(gums_set_user_unknown_str(*object, userdata->unknown_str), error); - - if (userdata->munged_dial) - SET_OR_FAIL(gums_set_user_munged_dial(*object, userdata->munged_dial), error); - - SET_OR_FAIL(gums_set_user_logon_divs(*object, userdata->logon_divs), error); - - if (userdata->hours) - SET_OR_FAIL(gums_set_user_hours(*object, userdata->hours_len, userdata->hours), error); - - SET_OR_FAIL(gums_set_user_unknown_3(*object, userdata->unknown_3), error); - SET_OR_FAIL(gums_set_user_unknown_5(*object, userdata->unknown_5), error); - SET_OR_FAIL(gums_set_user_unknown_6(*object, userdata->unknown_6), error); - - SET_OR_FAIL(gums_set_user_logon_time(*object, *(userdata->logon_time)), error); - SET_OR_FAIL(gums_set_user_logoff_time(*object, *(userdata->logoff_time)), error); - SET_OR_FAIL(gums_set_user_kickoff_time(*object, *(userdata->kickoff_time)), error); - SET_OR_FAIL(gums_set_user_pass_last_set_time(*object, *(userdata->pass_last_set_time)), error); - SET_OR_FAIL(gums_set_user_pass_can_change_time(*object, *(userdata->pass_can_change_time)), error); - SET_OR_FAIL(gums_set_user_pass_must_change_time(*object, *(userdata->pass_must_change_time)), error); - - pwd = data_blob(userdata->nt_pw_ptr, NT_HASH_LEN); - ret = gums_set_user_nt_pwd(*object, pwd); - data_blob_clear_free(&pwd); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(5, ("user_data_to_gums_object: failed to set nt password!\n")); - goto error; - } - pwd = data_blob(userdata->lm_pw_ptr, LM_HASH_LEN); - ret = gums_set_user_lm_pwd(*object, pwd); - data_blob_clear_free(&pwd); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(5, ("user_data_to_gums_object: failed to set lanman password!\n")); - goto error; - } - - ret = NT_STATUS_OK; - return ret; - -error: - talloc_destroy((*object)->mem_ctx); - *object = NULL; - return ret; -} - -static NTSTATUS group_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_group_data *groupdata) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - if (!object || !groupdata) { - DEBUG(0, ("tdbsam2_group_data_to_gums_object: no NULL pointers are accepted here!\n")); - return ret; + object->seq_num += 1; } - /* groupdata->xcounter */ - /* groupdata->sec_desc */ - - SET_OR_FAIL(gums_set_object_sid(*object, groupdata->group_sid), error); - SET_OR_FAIL(gums_set_object_name(*object, groupdata->name), error); - - if (groupdata->description) - SET_OR_FAIL(gums_set_object_description(*object, groupdata->description), error); - - if (groupdata->count) - SET_OR_FAIL(gums_set_group_members(*object, groupdata->count, groupdata->members), error); - - ret = NT_STATUS_OK; - return ret; - -error: - talloc_destroy((*object)->mem_ctx); - *object = NULL; - return ret; -} - -static NTSTATUS domain_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_domain_data *domdata) -{ - - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - if (!object || !*object || !domdata) { - DEBUG(0, ("tdbsam2_domain_data_to_gums_object: no NULL pointers are accepted here!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* domdata->xcounter */ - /* domdata->sec_desc */ - - SET_OR_FAIL(gums_set_object_sid(*object, domdata->dom_sid), error); - SET_OR_FAIL(gums_set_object_name(*object, domdata->name), error); - - if (domdata->description) - SET_OR_FAIL(gums_set_object_description(*object, domdata->description), error); - - ret = NT_STATUS_OK; - return ret; - -error: - talloc_destroy((*object)->mem_ctx); - *object = NULL; - return ret; -} - -static NTSTATUS priv_data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_priv_data *privdata) -{ - - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - if (!object || !*object || !privdata) { - DEBUG(0, ("tdbsam2_priv_data_to_gums_object: no NULL pointers are accepted here!\n")); - return ret; - } - - /* domdata->xcounter */ - /* domdata->sec_desc */ - - SET_OR_FAIL(gums_set_priv_luid_attr(*object, privdata->privilege), error); - SET_OR_FAIL(gums_set_object_name(*object, privdata->name), error); - - if (privdata->description) - SET_OR_FAIL(gums_set_object_description(*object, privdata->description), error); - - if (privdata->count) - SET_OR_FAIL(gums_set_priv_members(*object, privdata->count, privdata->members), error); - - ret = NT_STATUS_OK; - return ret; - -error: - talloc_destroy((*object)->mem_ctx); - *object = NULL; - return ret; -} + if (!NT_STATUS_IS_OK(ret = init_buffer_from_object(&(data.dptr), &(data.dsize), mem_ctx, object))) + goto done; -static NTSTATUS data_to_gums_object(GUMS_OBJECT **object, struct tdbsam2_object *data) -{ + fstrcpy(sidstr, sid_string_static(gums_get_object_sid(object))); + slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sidstr); + slprintf(namestr, sizeof(namestr) - 1, "%s%s", NAMEPREFIX, objname); - NTSTATUS ret; + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; - if (!object || !data) { - DEBUG(0, ("tdbsam2_user_data_to_gums_object: no NULL structure pointers are accepted here!\n")); - ret = NT_STATUS_INVALID_PARAMETER; + if ((r = tdb_store(tdb, key, data, flag)) != TDB_SUCCESS) { + DEBUG(0, ("store_object: Unable to modify TDBSAM!\n")); + DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb))); + DEBUGADD(0, (" occured while storing sid record (%s)\n", keystr)); + if (r == TDB_ERR_EXISTS) + ret = NT_STATUS_UNSUCCESSFUL; + else + ret = NT_STATUS_INTERNAL_DB_ERROR; goto done; } - ret = gums_create_object(object, data->type); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(5, ("tdbsam2_user_data_to_gums_object: error creating gums object!\n")); + data2.dptr = sidstr; + data2.dsize = strlen(sidstr) + 1; + key2.dptr = namestr; + key2.dsize = strlen(namestr) + 1; + + if ((r = tdb_store(tdb, key2, data2, flag)) != TDB_SUCCESS) { + DEBUG(0, ("store_object: Unable to modify TDBSAM!\n")); + DEBUGADD(0, (" Error: %s", tdb_errorstr(tdb))); + DEBUGADD(0, (" occured while storing name record (%s)\n", keystr)); + DEBUGADD(0, (" attempting rollback operation.\n")); + if ((tdb_delete(tdb, key)) != TDB_SUCCESS) { + DEBUG(0, ("store_object: Unable to rollback! Check database consitency!\n")); + } + if (r == TDB_ERR_EXISTS) + ret = NT_STATUS_UNSUCCESSFUL; + else + ret = NT_STATUS_INTERNAL_DB_ERROR; goto done; } - switch (data->type) { - - case GUMS_OBJ_DOMAIN: - ret = domain_data_to_gums_object(object, data->data.domain); - break; - - case GUMS_OBJ_NORMAL_USER: - ret = user_data_to_gums_object(object, data->data.user); - break; - - case GUMS_OBJ_GROUP: - case GUMS_OBJ_ALIAS: - ret = group_data_to_gums_object(object, data->data.group); - break; - - case GUMS_OBJ_PRIVILEGE: - ret = priv_data_to_gums_object(object, data->data.priv); - break; - - default: - ret = NT_STATUS_UNSUCCESSFUL; - } +/* TODO: update the general database counter */ +/* TODO: update this entry counter too */ done: + talloc_destroy(mem_ctx); return ret; } -#endif /* GUMM object functions */ @@ -788,26 +705,18 @@ static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj goto done; } - if (obj_type != GUMS_OBJ_PRIVILEGE) { - if (!sid) { - ret = NT_STATUS_INVALID_PARAMETER; + if (obj_type == GUMS_OBJ_DOMAIN) { + sid_copy(sid, get_global_sam_sid()); + } else { + if (!NT_STATUS_IS_OK(ret = get_next_sid(tdb, sid))) goto done; - } - - if (obj_type == GUMS_OBJ_DOMAIN) { - sid_copy(sid, get_global_sam_sid()); - } else { - if (!NT_STATUS_IS_OK(ret = get_next_sid(tdb, sid))) - goto done; - } - - gums_set_object_sid(go, sid); } + gums_set_object_sid(go, sid); gums_set_object_name(go, name); gums_set_object_seq_num(go, 1); - /*obj.data.domain->sec_desc*/ + /*obj.domain->sec_desc*/ switch (obj_type) { case GUMS_OBJ_NORMAL_USER: @@ -829,7 +738,6 @@ static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj gums_set_user_logon_divs(go, 168); gums_set_user_hours(go, 21, defhours); - gums_set_user_unknown_3(go, 0x00ffffff); gums_set_user_bad_password_count(go, 0); gums_set_user_logon_count(go, 0); gums_set_user_unknown_6(go, 0x000004ec); @@ -846,10 +754,6 @@ static NTSTATUS tdbsam2_new_object(DOM_SID *sid, const char *name, const int obj break; - case GUMS_OBJ_PRIVILEGE: - - break; - default: ret = NT_STATUS_OBJECT_TYPE_MISMATCH; goto done; @@ -864,6 +768,8 @@ done: return ret; } +/* TODO: handle privileges objects */ + static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid) { /* TODO: need to address privilege deletion */ @@ -882,7 +788,7 @@ static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid) return ret; } - slprintf(keystr, sizeof(keystr)-1, "%s%s", SIDPREFIX, sid_string_static(sid)); + slprintf(keystr, sizeof(keystr) - 1, "%s%s", SIDPREFIX, sid_string_static(sid)); key.dptr = keystr; key.dsize = strlen(keystr) + 1; @@ -909,18 +815,7 @@ static NTSTATUS tdbsam2_delete_object(const DOM_SID *sid) goto done; } - switch (go->type) { - case GUMS_OBJ_DOMAIN: - /* FIXME: SHOULD WE ALLOW TO DELETE DOMAINS ? */ - case GUMS_OBJ_GROUP: - case GUMS_OBJ_ALIAS: - case GUMS_OBJ_NORMAL_USER: - slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, gums_get_object_name(go)); - break; - default: - ret = NT_STATUS_OBJECT_TYPE_MISMATCH; - goto done; - } + slprintf(keystr, sizeof(keystr) - 1, "%s%s", NAMEPREFIX, gums_get_object_name(go)); key.dptr = keystr; key.dsize = strlen(keystr) + 1; @@ -956,10 +851,14 @@ static NTSTATUS tdbsam2_get_object_from_sid(GUMS_OBJECT **object, const DOM_SID } ret = get_object_by_sid(tdb, object, sid); - if (!NT_STATUS_IS_OK(ret) || (obj_type && gums_get_object_type(*object) != obj_type)) { + if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("tdbsam2_get_object_from_sid: %s\n", nt_errstr(ret))); goto error; } + if (obj_type && gums_get_object_type(*object) != obj_type) { + DEBUG(0, ("tdbsam2_get_object_from_sid: the object is not of the rerquested type!\n")); + goto error; + } tdb_close(tdb); return NT_STATUS_OK; @@ -970,10 +869,11 @@ error: return ret; } -static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *name, const int obj_type) +static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *domain, const char *name, const int obj_type) { NTSTATUS ret; TDB_CONTEXT *tdb; + fstring objname; if (!object || !name) { DEBUG(0, ("tdbsam2_get_object_from_name: no NULL pointers are accepted here!\n")); @@ -984,12 +884,27 @@ static NTSTATUS tdbsam2_get_object_from_name(GUMS_OBJECT **object, const char *n return ret; } + if (obj_type == GUMS_OBJ_DOMAIN) { + fstrcpy(objname, name); + } else { + if (!domain) { + domain = global_myname(); + } + fstrcpy(objname, domain); + fstrcat(objname, "\\"); + fstrcat(objname, name); + } + *object = NULL; ret = get_object_by_name(tdb, object, name); - if (!NT_STATUS_IS_OK(ret) || (obj_type && gums_get_object_type(*object) != obj_type)) { + if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("tdbsam2_get_object_from_name: %s\n", nt_errstr(ret))); goto error; } + if (obj_type && gums_get_object_type(*object) != obj_type) { + DEBUG(0, ("tdbsam2_get_object_from_name: the object is not of the rerquested type!\n")); + goto error; + } tdb_close(tdb); return NT_STATUS_OK; @@ -1072,7 +987,7 @@ static NTSTATUS tdbsam2_enumerate_objects_get_next(GUMS_OBJECT **object, void *h } while ((teo->key.dptr != NULL)) { - int len, version, type, size; + int len, version, type, size, seqnum; char *ptr; if (strncmp(teo->key.dptr, prefix, preflen)) { @@ -1099,6 +1014,7 @@ static NTSTATUS tdbsam2_enumerate_objects_get_next(GUMS_OBJECT **object, void *h len = tdb_unpack (data.dptr, data.dsize, TDB_FORMAT_STRING, &version, &type, + &seqnum, &size, &ptr); if (len == -1) { @@ -1166,7 +1082,7 @@ static NTSTATUS tdbsam2_enumerate_objects_stop(void *handle) return NT_STATUS_OK; } -static NTSTATUS tdbsam2_set_object(const GUMS_OBJECT *go) +static NTSTATUS tdbsam2_set_object(GUMS_OBJECT *go) { NTSTATUS ret; TDB_CONTEXT *tdb; @@ -1200,12 +1116,14 @@ static NTSTATUS (*unlock_sid) (const DOM_SID *sid); /* privileges related functions */ -static NTSTATUS (*add_members_to_privilege) (const LUID_ATTR *priv, const DOM_SID **members); -static NTSTATUS (*delete_members_from_privilege) (const LUID_ATTR *priv, const DOM_SID **members); -static NTSTATUS (*enumerate_privilege_members) (DOM_SID **members, const LUID_ATTR *priv); -static NTSTATUS (*get_sid_privileges) (DOM_SID **privs, const DOM_SID *sid); +static NTSTATUS (*get_privilege) (GUMS_OBJECT **object, const char *name); +static NTSTATUS (*add_members_to_privilege) (const char *name, const DOM_SID **members); +static NTSTATUS (*delete_members_from_privilege) (const char *name, const DOM_SID **members); +static NTSTATUS (*enumerate_privilege_members) (const char *name, DOM_SID **members); +static NTSTATUS (*get_sid_privileges) (const DOM_SID *sid, const char **privs); + /* warning!: set_privilege will overwrite a prior existing privilege if such exist */ -static NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv); +static NTSTATUS (*set_privilege) (GUMS_PRIVILEGE *priv); #endif static void free_tdbsam2_private_data(void **vp) @@ -1243,6 +1161,7 @@ static NTSTATUS init_tdbsam2(GUMS_FUNCTIONS *fns, const char *storage) fns->get_sid_groups = tdbsam2_get_sid_groups; fns->lock_sid = tdbsam2_lock_sid; fns->unlock_sid = tdbsam2_unlock_sid; + fns->get_privilege = tdbsam2_get_privilege; fns->add_members_to_privilege = tdbsam2_add_members_to_privilege; fns->delete_members_from_privilege = tdbsam2_delete_members_from_privilege; fns->enumerate_privilege_members = tdbsam2_enumerate_privilege_members; @@ -1280,7 +1199,7 @@ static NTSTATUS init_tdbsam2(GUMS_FUNCTIONS *fns, const char *storage) gums_init_builtin_domain(); } - gums_init_domain(get_global_sam_sid(), global_myname()); + gums_init_domain(get_global_sam_sid(), global_myname(), "The Domain"); } fns->private_data = &ts2_privs; -- cgit From b63c7081c593a78a9217899c201a1029707193b1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 21 Jan 2004 14:38:11 +0000 Subject: Display some nicer error messages for login via 'net'. I don't see a reason why we have so many special cases and not simply use nt_errstr(nt_status). Comments? Volker (This used to be commit 18fa3ee649102f4bd36f9b03702fe72d234b6a3a) --- source3/utils/net.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/utils/net.c b/source3/utils/net.c index 4d2b1eb439..b9081c3e31 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -155,6 +155,14 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip, NT_STATUS_V(NT_STATUS_LOGON_FAILURE)) d_printf("The username or password was not correct.\n"); + if (NT_STATUS_V(nt_status) == + NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT)) + d_printf("The account was locked out.\n"); + + if (NT_STATUS_V(nt_status) == + NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED)) + d_printf("The account was disabled.\n"); + return nt_status; } } -- cgit From 57d4be5159405734d32807f11c291c83c37db5f1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 21 Jan 2004 14:49:34 +0000 Subject: Fix compiler warning (This used to be commit 3ec0d3abe9c838ad78fb8fd6a390ea3d8d2b9fcf) --- source3/utils/net_rpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 93c13bf1f5..eb5a9634c8 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -303,6 +303,8 @@ static int net_rpc_oldjoin(int argc, const char **argv) if (rc) { d_printf("Failed to join domain\n"); } + + return rc; } /** -- cgit From 16f2ddf52ea04d421b4e3b570601906f76368d68 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Jan 2004 01:53:04 +0000 Subject: merge: * Add SIGABRT to fault handling so we now got a backtrace, if we crash in libldap with SIGABRT metze (This used to be commit 7f7b86e4b3815b112fe6881af6c261381f35286f) --- source3/lib/fault.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source3/lib/fault.c b/source3/lib/fault.c index df7830ef83..d8364ff225 100644 --- a/source3/lib/fault.c +++ b/source3/lib/fault.c @@ -47,6 +47,9 @@ static void fault_report(int sig) #endif #ifdef SIGBUS CatchSignal(SIGBUS,SIGNAL_CAST SIG_DFL); +#endif +#ifdef SIGABRT + CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL); #endif return; /* this should cause a core dump */ } @@ -74,7 +77,7 @@ void fault_setup(void (*fn)(void *)) #ifdef SIGBUS CatchSignal(SIGBUS,SIGNAL_CAST sig_fault); #endif +#ifdef SIGABRT + CatchSignal(SIGABRT,SIGNAL_CAST sig_fault); +#endif } - - - -- cgit From 77f2465c10db5688a361409a75a20a75bd2e9c51 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 22 Jan 2004 10:22:47 +0000 Subject: (merge from 3.0) Fix for debian Bug#225328 by LaMont Jones , where the failure of our LFS test on ia64 caused the _GNU_SOURCE define not to be added, causeing strndup() not to be defined... This was due to strdup() bein implicitly declared, and casting pointer->int->pointer. I'll look into when we really should define _GNU_SOURCE shortly, but the fix is correct anyway. Andrew Bartlett (This used to be commit ba9bc99d3df5098864513e73b0086e42cfab2a19) --- source3/configure.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/configure.in b/source3/configure.in index cf695eb05c..9d6e561327 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -494,6 +494,8 @@ exit(1); AC_TRY_RUN([ #include #include +#include +#include main() { #if _LFS64_LARGEFILE == 1 struct utsname uts; -- cgit From 614d1e31175de7a2defd7002722af8cd43bee701 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 22 Jan 2004 10:57:16 +0000 Subject: sorry for the conflict markers committed in by mistake :-( (This used to be commit c5634e0b713e594a32522df7a76c36639f772ed5) --- source3/passdb/pdb_gums.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/source3/passdb/pdb_gums.c b/source3/passdb/pdb_gums.c index c595a51e55..874199e04d 100644 --- a/source3/passdb/pdb_gums.c +++ b/source3/passdb/pdb_gums.c @@ -1,12 +1,6 @@ /* -<<<<<<< pdb_gums.c * 'Gums' password backend for samba - * Copyright (C) Simo Sorce 2003 -======= - * GUMS password backend for samba - * Copyright (C) Jelmer Vernooij 2002 - * Copyright (C) Andrew Bartlett 2003 ->>>>>>> 1.4 + * Copyright (C) Simo Sorce 2004 * * 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 the Free -- cgit From d3f269cd833c7452776008881ec1f1b695e0eabf Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 22 Jan 2004 14:44:45 +0000 Subject: fix previously committed old version by mistake (This used to be commit 4840b25dbd4d2eafc010389a711d42862d5fb0f0) --- source3/passdb/pdb_gums.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/passdb/pdb_gums.c b/source3/passdb/pdb_gums.c index 874199e04d..f34d3a94b5 100644 --- a/source3/passdb/pdb_gums.c +++ b/source3/passdb/pdb_gums.c @@ -1,6 +1,6 @@ /* - * 'Gums' password backend for samba - * Copyright (C) Simo Sorce 2004 + * GUMS password backend for samba + * Copyright (C) Simo Sorce 2003-2004 * * 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 the Free @@ -236,7 +236,7 @@ static NTSTATUS gums_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *acco if (!account || !name) return NT_STATUS_INVALID_PARAMETER; - if (!NT_STATUS_IS_OK(ret = ggwd->fns->get_object_from_name(&go, name, GUMS_OBJ_NORMAL_USER))) { + if (!NT_STATUS_IS_OK(ret = ggwd->fns->get_object_from_name(&go, global_myname(), name, GUMS_OBJ_NORMAL_USER))) { DEBUG(10, ("gums_getsampwnam: unable to find account with name %s", name)); return ret; } -- cgit From 72d68bb58cc8cd5d80397f037bb2d1c1ae49415c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 23 Jan 2004 12:07:28 +0000 Subject: Fix decoding of base64. We got the length wrong when the result was not an exact multiple of 3. I also wrote a torture test and it survived some minutes of random stuff coded/decoded up to 16 MB data. But that would be a bit too embarassing to commit... :-) Volker (This used to be commit 3fda2a0432a1dc7a0d28d83e35f6329bc30378e0) --- source3/lib/util_str.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index d93f39696f..822ab20628 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1838,6 +1838,8 @@ DATA_BLOB base64_decode_data_blob(const char *s) s++; i++; } + if (*s == '=') n -= 1; + /* fix up length */ decoded.length = n; return decoded; -- cgit From f06603428e4c8e7ad4140092fc4e8f61285af2ae Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 23 Jan 2004 12:58:07 +0000 Subject: Fix typo (This used to be commit f83606a058b934309bf1b2075747f504eb38575d) --- source3/nsswitch/wbinfo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index c7dc89d43f..4f6cc4225a 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -992,8 +992,7 @@ int main(int argc, char **argv) { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" }, { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" }, { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" }, - { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', - "Show all most info we have about the domain" }, + { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', "Show most of the info we have about the domain" }, { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" }, { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" }, { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" }, -- cgit From 5f8c17460724f0aaff3226798a0d5c7f7b25854e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 24 Jan 2004 10:56:36 +0000 Subject: (merge from 3.0) A Samba DC is nothing special these days - so every domain controller location packet from the client is not a DEBUG(1) event anymore... (Yes, we printed this for each of these UDP packets...) Andrew Bartlett (This used to be commit c84e8e91e4d4786ece6288a177f66f260d6e7945) --- source3/nmbd/nmbd_processlogon.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index 728796ea21..6b806f2a05 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -84,7 +84,7 @@ void process_logon_packet(struct packet_struct *p, char *buf,int len, memset(outbuf, 0, sizeof(outbuf)); if (!lp_domain_logons()) { - DEBUG(3,("process_logon_packet: Logon packet received from IP %s and domain \ + DEBUG(5,("process_logon_packet: Logon packet received from IP %s and domain \ logons are not enabled.\n", inet_ntoa(p->ip) )); return; } @@ -92,7 +92,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); pstrcpy(my_name, global_myname()); code = SVAL(buf,0); - DEBUG(1,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code)); + DEBUG(4,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code)); switch (code) { case 0: @@ -112,7 +112,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); pull_ascii_fstring(user_str, user); pull_ascii_fstring(getdc_str, getdc); - DEBUG(3,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n", + DEBUG(5,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n", mach_str,inet_ntoa(p->ip),user_str,token)); q = outbuf; @@ -211,7 +211,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); pull_ascii_fstring(mach_str, machine); - DEBUG(3,("process_logon_packet: GETDC request from %s at IP %s, \ + DEBUG(5,("process_logon_packet: GETDC request from %s at IP %s, \ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", mach_str,inet_ntoa(p->ip), reply_name, lp_workgroup(), QUERYFORPDC_R, (uint32)ntversion, (uint32)lmnttoken, @@ -248,14 +248,14 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", domainsidsize = IVAL(q, 0); q += 4; - DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d, len = %d\n", domainsidsize, len)); + DEBUG(5,("process_logon_packet: SAMLOGON sidsize %d, len = %d\n", domainsidsize, len)); if (domainsidsize < (len - PTR_DIFF(q, buf)) && (domainsidsize != 0)) { q += domainsidsize; q = ALIGN4(q, buf); } - DEBUG(3,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %ld\n", len, (unsigned long)PTR_DIFF(q, buf) )); + DEBUG(5,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %ld\n", len, (unsigned long)PTR_DIFF(q, buf) )); if (len - PTR_DIFF(q, buf) > 8) { /* with NT5 clients we can sometimes @@ -284,12 +284,12 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", */ pull_ucs2_pstring(ascuser, uniuser); pull_ucs2_fstring(asccomp, unicomp); - DEBUG(3,("process_logon_packet: SAMLOGON user %s\n", ascuser)); + DEBUG(5,("process_logon_packet: SAMLOGON user %s\n", ascuser)); fstrcpy(reply_name, "\\\\"); /* Here it wants \\LOGONSERVER. */ fstrcat(reply_name, my_name); - DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n", + DEBUG(5,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n", asccomp,inet_ntoa(p->ip), ascuser, reply_name, lp_workgroup(), SAMLOGON_R ,lmnttoken)); -- cgit From f1c7ebf5432b94dc24e4038530d2c72329c7de2a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Jan 2004 01:32:37 +0000 Subject: (merge from 3.0) Fix removal of attributes in LDAP - we would not actually remove the old value in the previous code. Andrew Bartlett (This used to be commit 971dd33244918cde6bf49a2f9c650da856d31cd6) --- source3/lib/smbldap.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 1156bd6639..150450c83d 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -425,7 +425,7 @@ BOOL fetch_ldap_pw(char **dn, char** pw) /* all of our string attributes are case insensitive */ - if (existed && (StrCaseCmp(oldval, newval) == 0)) { + if (existed && newval && (StrCaseCmp(oldval, newval) == 0)) { /* Believe it or not, but LDAP will deny a delete and an add at the same time if the values are the @@ -433,26 +433,26 @@ BOOL fetch_ldap_pw(char **dn, char** pw) return; } + if (existed) { + /* There has been no value before, so don't delete it. + * Here's a possible race: We might end up with + * duplicate attributes */ + /* By deleting exactly the value we found in the entry this + * should be race-free in the sense that the LDAP-Server will + * deny the complete operation if somebody changed the + * attribute behind our back. */ + /* This will also allow modifying single valued attributes + * in Novell NDS. In NDS you have to first remove attribute and then + * you could add new value */ + + smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval); + } + /* Regardless of the real operation (add or modify) we add the new value here. We rely on deleting the old value, should it exist. */ if ((newval != NULL) && (strlen(newval) > 0)) { - if (existed) { - /* There has been no value before, so don't delete it. - * Here's a possible race: We might end up with - * duplicate attributes */ - /* By deleting exactly the value we found in the entry this - * should be race-free in the sense that the LDAP-Server will - * deny the complete operation if somebody changed the - * attribute behind our back. */ - /* This will also allow modifying single valued attributes - * in Novell NDS. In NDS you have to first remove attribute and then - * you could add new value */ - - smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval); - } - smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval); } } -- cgit From 21ec3fa3e3ce09b5476e4d3d1452dc6477f8b8ef Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Jan 2004 01:34:08 +0000 Subject: (merge from 3.0) If we are providing strndup(), ensure we provide a prototype too. Andrew Bartlett (This used to be commit 5536c7448e88caa95b13c01956c37deee899dd92) --- source3/include/includes.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/include/includes.h b/source3/include/includes.h index 4e7913ea38..1867aeda12 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -991,6 +991,10 @@ struct smb_ldap_privates; char *strdup(const char *s); #endif +#ifndef HAVE_STRNDUP +char *strndup(const char *s, size_t size); +#endif + #ifndef HAVE_MEMMOVE void *memmove(void *dest,const void *src,int size); #endif -- cgit From 96faba97233674b6e4e7a86cd99a6fb052ffa055 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Jan 2004 01:35:31 +0000 Subject: (merge from 3.0) Fix the initialisation vectors for NTLM2, so that they at least make sense, even if they don't work yet. Andrew Bartlett (This used to be commit 40cc86d4b31efdee519cf2e2c9b62c4fdc885724) --- source3/libsmb/ntlmssp_sign.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 6ce7a76743..2347619e57 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -362,14 +362,14 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, ntlmssp_state->recv_sign_const, - ntlmssp_state->session_key, send_sign_const); + ntlmssp_state->session_key, recv_sign_const); dump_data_pw("NTLMSSP receive sign hash:\n", ntlmssp_state->recv_sign_hash, sizeof(ntlmssp_state->recv_sign_hash)); calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, ntlmssp_state->recv_seal_const, - ntlmssp_state->session_key, send_seal_const); + ntlmssp_state->session_key, recv_seal_const); dump_data_pw("NTLMSSP receive seal hash:\n", ntlmssp_state->recv_sign_hash, sizeof(ntlmssp_state->recv_sign_hash)); -- cgit From 3e0ecb4561d2af5c61b053d4c0e386172f6a9751 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Jan 2004 02:22:49 +0000 Subject: (merge from 3.0) Patch by Luca Bolcioni . Ensure we always initialise the session key. Fixes segfaults with security=server, and encrypt passwords = no. Andrew Bartlett (This used to be commit b5b6a5937ccb8126876e9ecf9b17cd95f6eec19d) --- source3/smbd/sesssetup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9405c065e1..c42a35e809 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -876,6 +876,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, session_key = data_blob(NULL, 16); SMBsesskeygen_lmv1(server_info->lm_session_key.data, lm_resp.data, session_key.data); + } else { + session_key = data_blob(NULL, 0); } data_blob_free(&lm_resp); -- cgit From f85a7bb04286fcab5e844b5457a4fc93da8d96f5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Jan 2004 08:51:58 +0000 Subject: (merge from 3.0) This adds client-side support for the unicode/SAMR password change scheme. As well as avoiding DOS charset issues, this scheme returns useful error codes, that we can map back via the pam interface. This patch also cleans up the interfaces used for password buffers, to avoid duplication of code. Andrew Bartlett (This used to be commit 8063b8b6c2eb30cb116988e265fb289109d7c348) --- source3/Makefile.in | 8 ++-- source3/libsmb/clirap.c | 12 +++--- source3/libsmb/passchange.c | 88 +++++++++++++++++++++++++++++++-------- source3/libsmb/smbencrypt.c | 68 +++++++++++++++--------------- source3/nsswitch/winbindd_pam.c | 10 +---- source3/rpc_client/cli_samr.c | 90 ++++++++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_samr.c | 14 +++---- source3/rpc_server/srv_samr_nt.c | 4 +- source3/utils/net_rpc.c | 8 +--- source3/utils/net_rpc_join.c | 9 +--- 10 files changed, 220 insertions(+), 91 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 6d69e03e5f..8eccf52d1a 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -228,7 +228,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/cliquota.o libsmb/clifsinfo.o \ libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \ libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \ - libsmb/passchange.o libsmb/doserr.o \ + libsmb/doserr.o \ $(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(LIBNMB_OBJ) LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \ @@ -416,7 +416,7 @@ SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \ - $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o + $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) libsmb/passchange.o lib/dummyroot.o SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \ $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) @@ -441,10 +441,10 @@ TESTPARM_OBJ = utils/testparm.o \ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \ $(LIB_OBJ) -SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) $(SECRETS_OBJ) \ +SMBPASSWD_OBJ = utils/smbpasswd.o libsmb/passchange.o $(PARAM_OBJ) $(SECRETS_OBJ) \ $(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\ $(UBIQX_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ) \ - $(SMBLDAP_OBJ) lib/dummyroot.o + $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) lib/dummyroot.o PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \ diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 79ad38fc8c..36bc403e0b 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -291,7 +291,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char *rparam = NULL; char *rdata = NULL; unsigned int rprcnt, rdrcnt; - pstring dos_new_password; if (strlen(user) >= sizeof(fstring)-1) { DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); @@ -317,10 +316,13 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char */ E_deshash(old_password, old_pw_hash); - clistr_push(cli, dos_new_password, new_password, sizeof(dos_new_password), STR_TERMINATE|STR_ASCII); - - if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) - return False; + encode_pw_buffer(data, new_password, STR_ASCII); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("make_oem_passwd_hash\n")); + dump_data(100, data, 516); +#endif + SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); /* * Now place the old password hash in the data. diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 41b6095520..dc0cbbcb7c 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -30,6 +30,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, struct nmb_name calling, called; struct cli_state cli; struct in_addr ip; + struct ntuser_creds creds; + + NTSTATUS result; *err_str = '\0'; @@ -66,18 +69,28 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - /* - * We should connect as the anonymous user here, in case - * the server has "must change password" checked... - * Thanks to for this fix. - */ + /* Given things like SMB signing, restrict anonymous and the like, + try an authenticated connection first */ + if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) { + /* + * We should connect as the anonymous user here, in case + * the server has "must change password" checked... + * Thanks to for this fix. + */ - if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { - slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } + if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + init_creds(&creds, "", "", NULL); + cli_init_creds(&cli, &creds); + } else { + init_creds(&creds, user_name, "", old_passwd); + cli_init_creds(&cli, &creds); + } if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", @@ -86,13 +99,54 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { - slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } + /* Try not to give the password away to easily */ + + cli.pipe_auth_flags = AUTH_PIPE_NTLMSSP; + cli.pipe_auth_flags |= AUTH_PIPE_SIGN; + cli.pipe_auth_flags |= AUTH_PIPE_SEAL; + if ( !cli_nt_session_open( &cli, PI_SAMR ) ) { + if (lp_client_lanman_auth()) { + if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + } else { + slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n", + remote_machine); + cli_shutdown(&cli); + return False; + } + } + + if (!NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name, + new_passwd, old_passwd))) { + + if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) + || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { + /* try the old Lanman method */ + if (lp_client_lanman_auth()) { + if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + } else { + slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n", + remote_machine); + cli_shutdown(&cli); + return False; + } + } else { + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, get_friendly_nt_error_msg(result)); + cli_shutdown(&cli); + return False; + } + } cli_shutdown(&cli); return True; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index cfcc24a1df..1d192b816a 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -70,20 +70,29 @@ void E_md4hash(const char *passwd, uchar p16[16]) * Creates the DES forward-only Hash of the users password in DOS ASCII charset * @param passwd password in 'unix' charset. * @param p16 return password hashed with DES, caller allocated 16 byte buffer + * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True + * @note p16 is filled in regardless */ -void E_deshash(const char *passwd, uchar p16[16]) +BOOL E_deshash(const char *passwd, uchar p16[16]) { + BOOL ret = True; fstring dospwd; ZERO_STRUCT(dospwd); /* Password must be converted to DOS charset - null terminated, uppercase. */ push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); - + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16((const unsigned char *)dospwd, p16); + if (strlen(dospwd) > 14) { + ret = False; + } + ZERO_STRUCT(dospwd); + + return ret; } /** @@ -219,24 +228,7 @@ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) { - int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); - - if (new_pw_len > 512) - { - DEBUG(0,("make_oem_passwd_hash: new password is too long.\n")); - return False; - } - - /* - * Now setup the data area. - * We need to generate a random fill - * for this area to make it harder to - * decrypt. JRA. - */ - generate_random_buffer((unsigned char *)data, 516, False); - push_string(NULL, &data[512 - new_pw_len], passwd, new_pw_len, - STR_NOALIGN | (unicode?STR_UNICODE:STR_ASCII)); - SIVAL(data, 512, new_pw_len); + encode_pw_buffer(data, passwd, (unicode?STR_UNICODE:STR_ASCII)); #ifdef DEBUG_PASSWORD DEBUG(100,("make_oem_passwd_hash\n")); @@ -473,37 +465,46 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password } /*********************************************************** - encode a password buffer. The caller gets to figure out - what to put in it. + encode a password buffer with a unicode password. The buffer + is filled with random data to make it harder to attack. ************************************************************/ -BOOL encode_pw_buffer(char buffer[516], char *new_pw, int new_pw_length) +BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) { - generate_random_buffer((unsigned char *)buffer, 516, True); + uchar new_pw[512]; + size_t new_pw_len; - memcpy(&buffer[512 - new_pw_length], new_pw, new_pw_length); + new_pw_len = push_string(NULL, new_pw, + password, + sizeof(new_pw), string_flags); + + memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); + + generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len, True); /* * The length of the new password is in the last 4 bytes of * the data buffer. */ - SIVAL(buffer, 512, new_pw_length); - + SIVAL(buffer, 512, new_pw_len); + ZERO_STRUCT(new_pw); return True; } + /*********************************************************** decode a password buffer *new_pw_len is the length in bytes of the possibly mulitbyte returned password including termination. ************************************************************/ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len) + int new_pwrd_size, uint32 *new_pw_len, + int string_flags) { int byte_len=0; /* Warning !!! : This function is called from some rpc call. - The password IN the buffer is a UNICODE string. + The password IN the buffer may be a UNICODE string. The password IN new_pwrd is an ASCII string If you reuse that code somewhere else check first. */ @@ -516,15 +517,16 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, dump_data(100, in_buffer, 516); #endif - /* Password cannot be longer than 128 characters */ - if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) { + /* Password cannot be longer than the size of the password buffer */ + if ( (byte_len < 0) || (byte_len > 512)) { DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); return False; } - /* decode into the return buffer. Buffer must be a pstring */ - *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, STR_UNICODE); + /* decode into the return buffer. Buffer length supplied */ + *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + byte_len, string_flags); #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 31698b4798..adbcd85435 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -508,18 +508,12 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) /* Get sam handle */ - if ( NT_STATUS_IS_ERR(result = cm_get_sam_handle(contact_domain, &hnd)) ) { + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(contact_domain, &hnd)) ) { DEBUG(1, ("could not get SAM handle on DC for %s\n", domain)); goto done; } - if (!cli_oem_change_password(hnd->cli, user, newpass, oldpass)) { - DEBUG(1, ("password change failed for user %s/%s\n", domain, - user)); - result = NT_STATUS_WRONG_PASSWORD; - } else { - result = NT_STATUS_OK; - } + result = cli_samr_chgpasswd_user(hnd->cli, mem_ctx, user, newpass, oldpass); done: state->response.data.auth.nt_status = NT_STATUS_V(result); diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 0eebcd0a6f..38d2119e83 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -1043,6 +1043,96 @@ NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* User change password */ + +NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const char *username, + const char *newpassword, + const char *oldpassword ) +{ + prs_struct qbuf, rbuf; + SAMR_Q_CHGPASSWD_USER q; + SAMR_R_CHGPASSWD_USER r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + uchar new_nt_password[516]; + uchar new_lm_password[516]; + uchar old_nt_hash[16]; + uchar old_lanman_hash[16]; + uchar old_nt_hash_enc[16]; + uchar old_lanman_hash_enc[16]; + + uchar new_nt_hash[16]; + uchar new_lanman_hash[16]; + + DEBUG(10,("cli_samr_query_dom_info\n")); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Calculate the MD4 hash (NT compatible) of the password */ + E_md4hash(oldpassword, old_nt_hash); + E_md4hash(newpassword, new_nt_hash); + + if (lp_client_lanman_auth() + && E_deshash(newpassword, new_lanman_hash) + && E_deshash(oldpassword, old_lanman_hash)) { + /* E_deshash returns false for 'long' passwords (> 14 + DOS chars). This allows us to match Win2k, which + does not store a LM hash for these passwords (which + would reduce the effective password length to 14) */ + + encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE); + + SamOEMhash( new_lm_password, old_nt_hash, 516); + E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc); + } else { + ZERO_STRUCT(new_lm_password); + ZERO_STRUCT(old_lanman_hash_enc); + } + + encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE); + + SamOEMhash( new_nt_password, old_nt_hash, 516); + E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username, + new_nt_password, + old_nt_hash_enc, + new_lm_password, + old_lanman_hash_enc); + + if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if (!NT_STATUS_IS_OK(result = r.status)) { + goto done; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* This function returns the bizzare set of (max_entries, max_size) required for the QueryDisplayInfo RPC to actually work against a domain controller with large (10k and higher) numbers of users. These values were diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index e0eb2958b3..7b2d886deb 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -6936,7 +6936,7 @@ BOOL samr_io_r_get_dom_pwinfo(const char *desc, SAMR_R_GET_DOM_PWINFO * r_u, make a SAMR_ENC_PASSWD structure. ********************************************************************/ -void init_enc_passwd(SAMR_ENC_PASSWD * pwd, char pass[512]) +void init_enc_passwd(SAMR_ENC_PASSWD * pwd, const char pass[512]) { ZERO_STRUCTP(pwd); @@ -6979,7 +6979,7 @@ BOOL samr_io_enc_passwd(const char *desc, SAMR_ENC_PASSWD * pwd, inits a SAMR_ENC_HASH structure. ********************************************************************/ -void init_enc_hash(SAMR_ENC_HASH * hsh, uchar hash[16]) +void init_enc_hash(SAMR_ENC_HASH * hsh, const uchar hash[16]) { ZERO_STRUCTP(hsh); @@ -7022,11 +7022,11 @@ inits a SAMR_R_GET_DOM_PWINFO structure. ********************************************************************/ void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u, - char *dest_host, char *user_name, - char nt_newpass[516], - uchar nt_oldhash[16], - char lm_newpass[516], - uchar lm_oldhash[16]) + const char *dest_host, const char *user_name, + const char nt_newpass[516], + const uchar nt_oldhash[16], + const char lm_newpass[516], + const uchar lm_oldhash[16]) { DEBUG(5, ("init_samr_q_chgpasswd_user\n")); diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 082e550928..b8de24cf39 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2815,7 +2815,7 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid) acct_ctrl = pdb_get_acct_ctrl(pwd); - if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) { + if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) { pdb_free_sam(&pwd); return False; } @@ -2887,7 +2887,7 @@ static BOOL set_user_info_pw(char *pass, DOM_SID *sid) ZERO_STRUCT(plaintext_buf); - if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) { + if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) { pdb_free_sam(&pwd); return False; } diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index eb5a9634c8..804faf3b9a 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1849,15 +1849,9 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli { SAM_USERINFO_CTR ctr; SAM_USER_INFO_24 p24; - fstring ucs2_trust_password; - int ucs2_pw_len; uchar pwbuf[516]; - ucs2_pw_len = push_ucs2(NULL, ucs2_trust_password, argv[1], - sizeof(ucs2_trust_password), 0); - - encode_pw_buffer((char *)pwbuf, ucs2_trust_password, - ucs2_pw_len); + encode_pw_buffer((char *)pwbuf, argv[1], STR_UNICODE); ZERO_STRUCT(ctr); ZERO_STRUCT(p24); diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index eb91a7df61..6bfeedc8a0 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -115,8 +115,6 @@ int net_rpc_join_newstyle(int argc, const char **argv) /* Password stuff */ char *clear_trust_password = NULL; - fstring ucs2_trust_password; - int ucs2_pw_len; uchar pwbuf[516]; SAM_USERINFO_CTR ctr; SAM_USER_INFO_24 p24; @@ -264,12 +262,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) E_md4hash(clear_trust_password, md4_trust_password); } - ucs2_pw_len = push_ucs2(NULL, ucs2_trust_password, - clear_trust_password, - sizeof(ucs2_trust_password), 0); - - encode_pw_buffer((char *)pwbuf, ucs2_trust_password, - ucs2_pw_len); + encode_pw_buffer(pwbuf, clear_trust_password, STR_UNICODE); /* Set password on machine account */ -- cgit From 2c1ddaea28da1e4444a2c51b8a46793cce542083 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Jan 2004 09:11:09 +0000 Subject: (merge from 3.0) Revise our server-side password change code to cope with the various different feilds that different clients send. (For example, not all clients send both password types). This also cleans up the code to make it clearer what is really going on, and to make better use of common functions. Andrew Bartlett (This used to be commit e5b5cd5966f2894c283383abe5d99fda524cbb9f) --- source3/smbd/chgpasswd.c | 267 ++++++++++++++++++++++++++++------------------- 1 file changed, 158 insertions(+), 109 deletions(-) diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 692e82680d..e3df8a11d0 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Andrew Bartlett 2001-2002 + Copyright (C) Andrew Bartlett 2001-2004 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 @@ -19,6 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* These comments regard the code to change the user's unix password: */ + /* fork a child process to exec passwd and write to its * tty to change a users password. This is running as the * user who is attempting to change the password. @@ -30,9 +32,6 @@ * was included as a client to change passwords using the 'passwd' program * on the remote machine. * - * This routine is called by set_user_password() in password.c only if ALLOW_PASSWORD_CHANGE - * is defined in the compiler directives located in the Makefile. - * * This code has been hacked by Bob Nance (nance@niehs.nih.gov) and Evan Patterson * (patters2@niehs.nih.gov) at the National Institute of Environmental Health Sciences * and rights to modify, distribute or incorporate this change to the CAP suite or @@ -62,10 +61,12 @@ extern struct passdb_ops pdb_ops; static NTSTATUS check_oem_password(const char *user, - uchar * lmdata, const uchar * lmhash, - const uchar * ntdata, const uchar * nthash, - SAM_ACCOUNT **hnd, char *new_passwd, - int new_passwd_size); + uchar password_encrypted_with_lm_hash[516], + const uchar old_lm_hash_encrypted[16], + uchar password_encrypted_with_nt_hash[516], + const uchar old_nt_hash_encrypted[16], + SAM_ACCOUNT **hnd, char *new_passwd, + int new_passwd_size); #if ALLOW_CHANGE_PASSWORD @@ -565,7 +566,7 @@ the string %%u, and the given string %s does not.\n", passwordprogram )); BOOL chgpasswd(const char *name, const struct passwd *pass, const char *oldpass, const char *newpass, BOOL as_root) { - DEBUG(0, ("chgpasswd: Password changing not compiled in (user=%s)\n", name)); + DEBUG(0, ("chgpasswd: Unix Password changing not compiled in (user=%s)\n", name)); return (False); } #endif /* ALLOW_CHANGE_PASSWORD */ @@ -705,14 +706,19 @@ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2) ************************************************************/ NTSTATUS pass_oem_change(char *user, - uchar * lmdata, uchar * lmhash, - uchar * ntdata, uchar * nthash) + uchar password_encrypted_with_lm_hash[516], + const uchar old_lm_hash_encrypted[16], + uchar password_encrypted_with_nt_hash[516], + const uchar old_nt_hash_encrypted[16]) { - fstring new_passwd; + pstring new_passwd; SAM_ACCOUNT *sampass = NULL; - NTSTATUS nt_status = check_oem_password(user, lmdata, lmhash, ntdata, nthash, - &sampass, new_passwd, sizeof(new_passwd)); - + NTSTATUS nt_status = check_oem_password(user, password_encrypted_with_lm_hash, + old_lm_hash_encrypted, + password_encrypted_with_nt_hash, + old_nt_hash_encrypted, + &sampass, new_passwd, sizeof(new_passwd)); + if (!NT_STATUS_IS_OK(nt_status)) return nt_status; @@ -729,33 +735,42 @@ NTSTATUS pass_oem_change(char *user, } /*********************************************************** - Code to check the OEM hashed password. + Decrypt and verify a user password change. - this function ignores the 516 byte nt OEM hashed password - but does use the lm OEM password to check the nt hashed-hash. + The 516 byte long buffers are encrypted with the old NT and + old LM passwords, and if the NT passwords are present, both + buffers contain a unicode string. + After decrypting the buffers, check the password is correct by + matching the old hashed passwords with the passwords in the passdb. + ************************************************************/ static NTSTATUS check_oem_password(const char *user, - uchar * lmdata, const uchar * lmhash, - const uchar * ntdata, const uchar * nthash, - SAM_ACCOUNT **hnd, char *new_passwd, - int new_passwd_size) + uchar password_encrypted_with_lm_hash[516], + const uchar old_lm_hash_encrypted[16], + uchar password_encrypted_with_nt_hash[516], + const uchar old_nt_hash_encrypted[16], + SAM_ACCOUNT **hnd, char *new_passwd, + int new_passwd_size) { static uchar null_pw[16]; static uchar null_ntpw[16]; SAM_ACCOUNT *sampass = NULL; + char *password_encrypted; + const char *encryption_key; const uint8 *lanman_pw, *nt_pw; uint16 acct_ctrl; - int new_pw_len; - uchar new_ntp16[16]; - uchar unenc_old_ntpw[16]; - uchar new_p16[16]; - uchar unenc_old_pw[16]; + uint32 new_pw_len; + uchar new_nt_hash[16]; + uchar old_nt_hash_plain[16]; + uchar new_lm_hash[16]; + uchar old_lm_hash_plain[16]; char no_pw[2]; BOOL ret; - BOOL nt_pass_set = (ntdata != NULL && nthash != NULL); + BOOL nt_pass_set = (password_encrypted_with_nt_hash && old_nt_hash_encrypted); + BOOL lm_pass_set = (password_encrypted_with_lm_hash && old_lm_hash_encrypted); *hnd = NULL; @@ -768,97 +783,152 @@ static NTSTATUS check_oem_password(const char *user, if (ret == False) { DEBUG(0, ("check_oem_password: getsmbpwnam returned NULL\n")); pdb_free_sam(&sampass); - return NT_STATUS_WRONG_PASSWORD; - /* - TODO: check what Win2k returns for this: - return NT_STATUS_NO_SUCH_USER; - */ + return NT_STATUS_NO_SUCH_USER; } acct_ctrl = pdb_get_acct_ctrl(sampass); if (acct_ctrl & ACB_DISABLED) { - DEBUG(0,("check_lanman_password: account %s disabled.\n", user)); + DEBUG(2,("check_lanman_password: account %s disabled.\n", user)); pdb_free_sam(&sampass); return NT_STATUS_ACCOUNT_DISABLED; } - /* construct a null password (in case one is needed */ - no_pw[0] = 0; - no_pw[1] = 0; - nt_lm_owf_gen(no_pw, null_ntpw, null_pw); - - /* save pointers to passwords so we don't have to keep looking them up */ - lanman_pw = pdb_get_lanman_passwd(sampass); - nt_pw = pdb_get_nt_passwd(sampass); + if (acct_ctrl & ACB_PWNOTREQ && lp_null_passwords()) { + /* construct a null password (in case one is needed */ + no_pw[0] = 0; + no_pw[1] = 0; + nt_lm_owf_gen(no_pw, null_ntpw, null_pw); + lanman_pw = null_pw; + nt_pw = null_pw; - /* check for null passwords */ - if (lanman_pw == NULL) { - if (!(acct_ctrl & ACB_PWNOTREQ)) { - DEBUG(0,("check_oem_password: no lanman password !\n")); - pdb_free_sam(&sampass); - return NT_STATUS_WRONG_PASSWORD; + } else { + /* save pointers to passwords so we don't have to keep looking them up */ + if (lp_lanman_auth()) { + lanman_pw = pdb_get_lanman_passwd(sampass); + } else { + lanman_pw = NULL; } + nt_pw = pdb_get_nt_passwd(sampass); } - - if (pdb_get_nt_passwd(sampass) == NULL && nt_pass_set) { - if (!(acct_ctrl & ACB_PWNOTREQ)) { - DEBUG(0,("check_oem_password: no ntlm password !\n")); - pdb_free_sam(&sampass); - return NT_STATUS_WRONG_PASSWORD; - } + + if (nt_pw && nt_pass_set) { + /* IDEAL Case: passwords are in unicode, and we can + * read use the password encrypted with the NT hash + */ + password_encrypted = password_encrypted_with_nt_hash; + encryption_key = nt_pw; + } else if (lanman_pw && lm_pass_set) { + /* password may still be in unicode, but use LM hash version */ + password_encrypted = password_encrypted_with_lm_hash; + encryption_key = lanman_pw; + } else if (nt_pass_set) { + DEBUG(1, ("NT password change supplied for user %s, but we have no NT password to check it with\n", + user)); + pdb_free_sam(&sampass); + return NT_STATUS_WRONG_PASSWORD; + } else if (lm_pass_set) { + DEBUG(1, ("LM password change supplied for user %s, but we have no LanMan password to check it with\n", + user)); + pdb_free_sam(&sampass); + return NT_STATUS_WRONG_PASSWORD; + } else { + DEBUG(1, ("password change requested for user %s, but no password supplied!\n", + user)); + pdb_free_sam(&sampass); + return NT_STATUS_WRONG_PASSWORD; } - - /* - * Call the hash function to get the new password. - */ - SamOEMhash( lmdata, lanman_pw, 516); /* - * The length of the new password is in the last 4 bytes of - * the data buffer. + * Decrypt the password with the key */ + SamOEMhash( password_encrypted, encryption_key, 516); - new_pw_len = IVAL(lmdata, 512); - - if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1) { - DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len)); + if ( !decode_pw_buffer(password_encrypted, new_passwd, new_passwd_size, &new_pw_len, + nt_pass_set ? STR_UNICODE : STR_ASCII)) { pdb_free_sam(&sampass); return NT_STATUS_WRONG_PASSWORD; } - if (nt_pass_set) { - /* - * nt passwords are in unicode - */ - pull_ucs2(NULL, new_passwd, - (const smb_ucs2_t *)&lmdata[512 - new_pw_len], - new_passwd_size, new_pw_len, 0); - } else { - memcpy(new_passwd, &lmdata[512 - new_pw_len], new_pw_len); - new_passwd[new_pw_len] = 0; - } - /* * To ensure we got the correct new password, hash it and * use it as a key to test the passed old password. */ - nt_lm_owf_gen(new_passwd, new_ntp16, new_p16); + if (nt_pass_set) { + /* NT passwords, verify the NT hash. */ + + /* Calculate the MD4 hash (NT compatible) of the password */ + memset(new_nt_hash, '\0', 16); + E_md4hash(new_passwd, new_nt_hash); + + if (nt_pw) { + /* + * Now use new_nt_hash as the key to see if the old + * password matches. + */ + D_P16(new_nt_hash, old_nt_hash_encrypted, old_nt_hash_plain); + + if (memcmp(nt_pw, old_nt_hash_plain, 16)) { + DEBUG(0,("check_oem_password: old lm password doesn't match.\n")); + pdb_free_sam(&sampass); + return NT_STATUS_WRONG_PASSWORD; + } + + /* We could check the LM password here, but there is + * little point, we already know the password is + * correct, and the LM password might not even be + * present. */ + + /* Further, LM hash generation algorithms + * differ with charset, so we could + * incorrectly fail a perfectly valid password + * change */ +#ifdef DEBUG_PASSWORD + DEBUG(100, + ("check_oem_password: password %s ok\n", new_passwd)); +#endif + *hnd = sampass; + return NT_STATUS_OK; + } + + if (lanman_pw) { + /* + * Now use new_nt_hash as the key to see if the old + * LM password matches. + */ + D_P16(new_nt_hash, old_lm_hash_encrypted, old_lm_hash_plain); + + if (memcmp(lanman_pw, old_lm_hash_plain, 16)) { + DEBUG(0,("check_oem_password: old lm password doesn't match.\n")); + pdb_free_sam(&sampass); + return NT_STATUS_WRONG_PASSWORD; + } +#ifdef DEBUG_PASSWORD + DEBUG(100, + ("check_oem_password: password %s ok\n", new_passwd)); +#endif + *hnd = sampass; + return NT_STATUS_OK; + } + } + + if (lanman_pw && lm_pass_set) { + + E_deshash(new_passwd, new_lm_hash); - if (!nt_pass_set) { /* - * Now use new_p16 as the key to see if the old + * Now use new_lm_hash as the key to see if the old * password matches. */ - D_P16(new_p16, lmhash, unenc_old_pw); - - if (memcmp(lanman_pw, unenc_old_pw, 16)) { + D_P16(new_lm_hash, old_lm_hash_encrypted, old_lm_hash_plain); + + if (memcmp(lanman_pw, old_lm_hash_plain, 16)) { DEBUG(0,("check_oem_password: old lm password doesn't match.\n")); pdb_free_sam(&sampass); return NT_STATUS_WRONG_PASSWORD; } - + #ifdef DEBUG_PASSWORD DEBUG(100, ("check_oem_password: password %s ok\n", new_passwd)); @@ -867,30 +937,9 @@ static NTSTATUS check_oem_password(const char *user, return NT_STATUS_OK; } - /* - * Now use new_p16 as the key to see if the old - * password matches. - */ - D_P16(new_ntp16, lmhash, unenc_old_pw); - D_P16(new_ntp16, nthash, unenc_old_ntpw); - - if (memcmp(lanman_pw, unenc_old_pw, 16)) { - DEBUG(0,("check_oem_password: old lm password doesn't match.\n")); - pdb_free_sam(&sampass); - return NT_STATUS_WRONG_PASSWORD; - } - - if (memcmp(nt_pw, unenc_old_ntpw, 16)) { - DEBUG(0,("check_oem_password: old nt password doesn't match.\n")); - pdb_free_sam(&sampass); - return NT_STATUS_WRONG_PASSWORD; - } -#ifdef DEBUG_PASSWORD - DEBUG(100, ("check_oem_password: password %s ok\n", new_passwd)); -#endif - - *hnd = sampass; - return NT_STATUS_OK; + /* should not be reached */ + pdb_free_sam(&sampass); + return NT_STATUS_WRONG_PASSWORD; } /*********************************************************** -- cgit From 40fced520587a23bb3704d02af82424ae694c31f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 27 Jan 2004 10:19:11 +0000 Subject: (merge from 3.0) Clarify comment on set_effective_uid() Andrew Bartlett (This used to be commit 0a9afefb55e9071fd21ea280095555f423571853) --- source3/lib/util_sec.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/source3/lib/util_sec.c b/source3/lib/util_sec.c index 7c2576ed91..26be27ea51 100644 --- a/source3/lib/util_sec.c +++ b/source3/lib/util_sec.c @@ -177,8 +177,16 @@ void gain_root_group_privilege(void) /**************************************************************************** - Set *only* the effective uid. - we want to end up with ruid==0 and euid==uid + Set effective uid, and possibly the real uid too. + We want to end up with either: + + ruid==uid and euid==uid + + or + + ruid==0 and euid==uid + + depending on what the local OS will allow us to regain root from. ****************************************************************************/ void set_effective_uid(uid_t uid) { -- cgit From a6676764a855a63828fb7c4997a7fd7f38ba7cff Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 27 Jan 2004 15:28:59 +0000 Subject: bug 977 - don't create a homes share for a user if a static share already exists by the same name (This used to be commit e589f6502fc280d5f89b399c6cef167e26773062) --- source3/smbd/password.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 494d9ecd43..36e3fb4738 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -254,7 +254,13 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n", vuser->user.unix_name, vuser->unix_homedir)); - vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir); + + /* only add the home directory if there doesn't exist a static share by that name */ + if ( lp_servicenumber(vuser->user.unix_name) == -1 ) { + vuser->homes_snum = add_home_service(vuser->user.unix_name, + vuser->user.unix_name, vuser->unix_homedir); + } + } else { vuser->homes_snum = -1; } -- cgit From 381adaf5cfc6a8f5dcf65c25351d5996e89090f3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Jan 2004 17:56:15 +0000 Subject: Don't built gums by default (to enable it, run ./configure --with-static-modules=pdb_gums) (This used to be commit df7666161f75b61058a017fea04b733751d5ac06) --- source3/Makefile.in | 5 ++--- source3/configure.in | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 8eccf52d1a..9f26e13421 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -288,14 +288,13 @@ RPC_CLIENT_OBJ = rpc_client/cli_pipe.o LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o -GUMS_OBJ = sam/gums.o sam/gums_api.o sam/gums_helper.o +GUMS_OBJ = sam/gums.o sam/gums_api.o sam/gums_helper.o @GUMS_STATIC@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ passdb/machine_sid.o passdb/util_sam_sid.o passdb/pdb_compat.o \ - passdb/privileges.o passdb/lookup_sid.o @PDB_STATIC@ \ - $(GUMS_OBJ) @GUMS_STATIC@ passdb/pdb_sql.o + passdb/privileges.o passdb/lookup_sid.o @PDB_STATIC@ passdb/pdb_sql.o XML_OBJ = passdb/pdb_xml.o MYSQL_OBJ = passdb/pdb_mysql.o diff --git a/source3/configure.in b/source3/configure.in index 9d6e561327..bdcaa4cacb 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -319,7 +319,7 @@ DYNEXP= dnl Add modules that have to be built by default here dnl These have to be built static: -default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_epmapper auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin pdb_gums gums_tdbsam2" +default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_epmapper auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin gums_tdbsam2" dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap charset_CP850 charset_CP437" @@ -4314,7 +4314,7 @@ SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o, "bin/ldapsam.$SHLIBEXT", PDB, SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB) SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB) SMB_MODULE(pdb_guest, passdb/pdb_guest.o, "bin/guest.$SHLIBEXT", PDB) -SMB_MODULE(pdb_gums, passdb/pdb_gums.o, "bin/gums.$SHLIBEXT", PDB) +SMB_MODULE(pdb_gums, [passdb/pdb_gums.o \$(GUMS_OBJ)], "bin/gums.$SHLIBEXT", PDB) SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o) SMB_MODULE(gums_tdbsam2, sam/gums_tdbsam2.o, "bin/tdbsam2.$SHLIBEXT", GUMS) -- cgit From 8ce5bd47a346e8a8cc2cbd52e8fd71ee06799884 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Wed, 28 Jan 2004 23:13:22 +0000 Subject: This is Simo's patch for the NetShareEnum() bug which caused us to return share names longer than 12 bytes. The function now filters out names longer than 12 bytes (which is compatible with Windows behavior). A better fix might be to store short names along with any names longer than 12 bytes, using a simple (very) name mangling. I'm committing in HEAD. If there are no problems this can easily be merged into 3.0.x. Chris -)----- (This used to be commit 6a8a64dc87863b39490d7f22a7d107e6916584f2) --- source3/smbd/lanman.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index c53889a7a4..c4df84e76c 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -1465,12 +1465,24 @@ static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *para } /**************************************************************************** - view list of shares available - ****************************************************************************/ -static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,char *data, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) + View the list of available shares. + + This function is the server side of the NetShareEnum() RAP call. + It fills the return buffer with share names and share comments. + Note that the return buffer normally (in all known cases) allows only + twelve byte strings for share names (plus one for a nul terminator). + Share names longer than 12 bytes must be skipped. + ****************************************************************************/ +static BOOL api_RNetShareEnum( connection_struct *conn, + uint16 vuid, + char *param, + char *data, + int mdrcnt, + int mprcnt, + char **rdata, + char **rparam, + int *rdata_len, + int *rparam_len ) { char *str1 = param+2; char *str2 = skip_string(str1,1); @@ -1490,7 +1502,9 @@ static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,c data_len = fixed_len = string_len = 0; for (i=0;i Date: Thu, 29 Jan 2004 02:41:57 +0000 Subject: Remove an unused parameter in winbindd (reload_services_file) (This used to be commit 9a81094a0f0ca5c209f640c48b77522e5f81d28e) --- source3/nsswitch/winbindd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 3124ef6378..8a0d0f7573 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -30,7 +30,7 @@ BOOL opt_dual_daemon = True; /* Reload configuration */ -static BOOL reload_services_file(BOOL test) +static BOOL reload_services_file(void) { BOOL ret; @@ -40,7 +40,6 @@ static BOOL reload_services_file(BOOL test) pstrcpy(fname,lp_configfile()); if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) { pstrcpy(dyn_CONFIGFILE,fname); - test = False; } } @@ -194,7 +193,7 @@ static void msg_reload_services(int msg_type, pid_t src, void *buf, size_t len) { /* Flush various caches */ flush_caches(); - reload_services_file(True); + reload_services_file(); } /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/ @@ -843,7 +842,7 @@ int main(int argc, char **argv) DEBUG(1, ("winbindd version %s started.\n", SAMBA_VERSION_STRING) ); DEBUGADD( 1, ( "Copyright The Samba Team 2000-2004\n" ) ); - if (!reload_services_file(False)) { + if (!reload_services_file()) { DEBUG(0, ("error opening config file\n")); exit(1); } -- cgit From 641023037dfa733415dec287d7738762cc39181b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 Jan 2004 06:28:27 +0000 Subject: updated the head branch as well (This used to be commit 467a58af346b30291b69b5d8da7f1b21d518fc1d) --- source3/nsswitch/winbind_nss_aix.c | 926 +++++++++++++++++++++++++++++++------ 1 file changed, 778 insertions(+), 148 deletions(-) diff --git a/source3/nsswitch/winbind_nss_aix.c b/source3/nsswitch/winbind_nss_aix.c index 3d2f01b93c..3e00e54e5c 100644 --- a/source3/nsswitch/winbind_nss_aix.c +++ b/source3/nsswitch/winbind_nss_aix.c @@ -1,12 +1,12 @@ /* Unix SMB/CIFS implementation. - AIX loadable authentication module, providing identification - routines against Samba winbind/Windows NT Domain + AIX loadable authentication module, providing identification and + authentication routines against Samba winbind/Windows NT Domain Copyright (C) Tim Potter 2003 Copyright (C) Steve Roylance 2003 - Copyright (C) Andrew Tridgell 2003 + Copyright (C) Andrew Tridgell 2003-2004 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -25,9 +25,24 @@ */ /* + + To install this module copy nsswitch/WINBIND to /usr/lib/security and add + "WINBIND" in /usr/lib/security/methods.cfg and /etc/security/user + + Note that this module also provides authentication and password + changing routines, so you do not need to install the winbind PAM + module. + see http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/kernextc/sec_load_mod.htm - for information in the interface that this module implements + for some information in the interface that this module implements + + Many thanks to Julianne Haugh for explaining some of the finer + details of this interface. + + To debug this module use uess_test.c (which you can get from tridge) + or set "options=debug" in /usr/lib/security/methods.cfg + */ #include @@ -38,79 +53,24 @@ #include "winbind_client.h" -/* - the documentation doesn't say so, but experimentation shows that all - of the functions need to return static data, and the area can be - freed only when the same function is called again, or the close - method is called on the module. Note that this matches the standard - behaviour of functions like getpwnam(). - - The most puzzling thing about this AIX interface is that it seems to - offer no way of providing a user or group enumeration method. You - can find out any amount of detail about a user or group once you - know the name, but you can't obtain a list of those names. If anyone - does find out how to do this then please let me know (yes, I should - be able to find out as I work for IBM, and this is an IBM interface, - but finding the right person to ask is a mammoth task!) - - tridge@samba.org October 2003 -*/ - +#define WB_AIX_ENCODED '_' -/* - each function uses one of the following lists of memory, declared - static in each backend method. This allows the function to destroy - the memory when that backend is called next time -*/ -struct mem_list { - struct mem_list *next, *prev; - void *p; -}; +static int debug_enabled; -/* allocate some memory on a mem_list */ -static void *list_alloc(struct mem_list **list, size_t size) +static void logit(const char *format, ...) { - struct mem_list *m; - m = malloc(sizeof(*m)); - if (!m) { - errno = ENOMEM; - return NULL; - } - m->p = malloc(size); - if (!m->p) { - errno = ENOMEM; - free(m); - return NULL; - } - m->next = *list; - m->prev = NULL; - if (*list) { - (*list)->prev = m; + va_list ap; + FILE *f; + if (!debug_enabled) { + return; } - (*list) = m; - return m->p; -} - -/* duplicate a string using list_alloc() */ -static char *list_strdup(struct mem_list **list, const char *s) -{ - char *ret = list_alloc(list, strlen(s)+1); - if (!ret) return NULL; - strcpy(ret, s); - return ret; -} - -/* destroy a mem_list */ -static void list_destory(struct mem_list **list) -{ - struct mem_list *m, *next; - for (m=*list; m; m=next) { - next = m->next; - free(m->p); - free(m); - } - (*list) = NULL; + f = fopen("/tmp/WINBIND_DEBUG.log", "a"); + if (!f) return; + va_start(ap, format); + vfprintf(f, format, ap); + va_end(ap); + fclose(f); } @@ -124,58 +84,147 @@ static void list_destory(struct mem_list **list) } \ } while (0) -/* - fill a struct passwd from a winbindd_pw struct, using memory from a mem_list +#define STRCPY_RET(dest, src) \ +do { \ + if (strlen(src)+1 > sizeof(dest)) { errno = EINVAL; return -1; } \ + strcpy(dest, src); \ +} while (0) + +#define STRCPY_RETNULL(dest, src) \ +do { \ + if (strlen(src)+1 > sizeof(dest)) { errno = EINVAL; return NULL; } \ + strcpy(dest, src); \ +} while (0) + + +/* free a passwd structure */ +static void free_pwd(struct passwd *pwd) +{ + free(pwd->pw_name); + free(pwd->pw_passwd); + free(pwd->pw_gecos); + free(pwd->pw_dir); + free(pwd->pw_shell); + free(pwd); +} + +/* free a group structure */ +static void free_grp(struct group *grp) +{ + int i; + + free(grp->gr_name); + free(grp->gr_passwd); + + if (!grp->gr_mem) { + free(grp); + return; + } + + for (i=0; grp->gr_mem[i]; i++) { + free(grp->gr_mem[i]); + } + + free(grp->gr_mem); + free(grp); +} + + +/* replace commas with nulls, and null terminate */ +static void replace_commas(char *s) +{ + char *p, *p0=s; + for (p=strchr(s, ','); p; p = strchr(p+1, ',')) { + *p=0; + p0 = p+1; + } + + p0[strlen(p0)+1] = 0; +} + + +/* the decode_*() routines are used to cope with the fact that AIX 5.2 + and below cannot handle user or group names longer than 8 + characters in some interfaces. We use the normalize method to + provide a mapping to a username that fits, by using the form '_UID' + or '_GID'. + + this only works if you can guarantee that the WB_AIX_ENCODED char + is not used as the first char of any other username */ -static struct passwd *fill_pwent(struct mem_list **list, struct winbindd_pw *pw) +static unsigned decode_id(const char *name) { - struct passwd *result; + unsigned id; + sscanf(name+1, "%u", &id); + return id; +} - if (!(result = list_alloc(list, sizeof(struct passwd)))) { +static char *decode_user(const char *name) +{ + struct passwd *pwd; + unsigned id; + char *ret; + static struct passwd *wb_aix_getpwuid(uid_t uid); + + sscanf(name+1, "%u", &id); + pwd = wb_aix_getpwuid(id); + if (!pwd) { return NULL; } + ret = strdup(pwd->pw_name); - ZERO_STRUCTP(result); + free_pwd(pwd); + + logit("decoded '%s' -> '%s'\n", name, ret); + + return ret; +} - result->pw_uid = pw->pw_uid; - result->pw_gid = pw->pw_gid; - /* strings */ - if ((result->pw_name = list_strdup(list, pw->pw_name)) == NULL || - (result->pw_passwd = list_strdup(list, pw->pw_passwd)) == NULL || - (result->pw_gecos = list_strdup(list, pw->pw_gecos)) == NULL || - (result->pw_dir = list_strdup(list, pw->pw_dir)) == NULL || - (result->pw_shell = list_strdup(list, pw->pw_shell)) == NULL) { +/* + fill a struct passwd from a winbindd_pw struct, allocating as a single block +*/ +static struct passwd *fill_pwent(struct winbindd_pw *pw) +{ + struct passwd *result; + + result = calloc(1, sizeof(struct passwd)); + if (!result) { + errno = ENOMEM; return NULL; } + + result->pw_uid = pw->pw_uid; + result->pw_gid = pw->pw_gid; + result->pw_name = strdup(pw->pw_name); + result->pw_passwd = strdup(pw->pw_passwd); + result->pw_gecos = strdup(pw->pw_gecos); + result->pw_dir = strdup(pw->pw_dir); + result->pw_shell = strdup(pw->pw_shell); return result; } /* - fill a struct group from a winbindd_pw struct, using memory from a mem_list + fill a struct group from a winbindd_pw struct, allocating as a single block */ -static struct group *fill_grent(struct mem_list **list, struct winbindd_gr *gr, char *gr_mem) +static struct group *fill_grent(struct winbindd_gr *gr, char *gr_mem) { int i; - char *tst; struct group *result; - char *name, *p; + char *p, *name; - if (!(result = list_alloc(list, sizeof(struct group)))) { + result = calloc(1, sizeof(struct group)); + if (!result) { + errno = ENOMEM; return NULL; } - ZERO_STRUCTP(result); - result->gr_gid = gr->gr_gid; - /* Group name */ - if ((result->gr_name = list_strdup(list, gr->gr_name)) == NULL || - (result->gr_passwd = list_strdup(list, gr->gr_passwd)) == NULL) { - return NULL; - } + result->gr_name = strdup(gr->gr_name); + result->gr_passwd = strdup(gr->gr_passwd); /* Group membership */ if ((gr->num_gr_mem < 0) || !gr_mem) { @@ -187,30 +236,26 @@ static struct group *fill_grent(struct mem_list **list, struct winbindd_gr *gr, return result; } - tst = list_alloc(list, (gr->num_gr_mem + 1) * sizeof(char *)); - if (!tst) { + result->gr_mem = (char **)malloc(sizeof(char *) * (gr->num_gr_mem+1)); + if (!result->gr_mem) { + errno = ENOMEM; return NULL; } - - result->gr_mem = (char **)tst; /* Start looking at extra data */ i=0; for (name = strtok_r(gr_mem, ",", &p); name; name = strtok_r(NULL, ",", &p)) { - if (i >= gr->num_gr_mem) { - return NULL; - } - (result->gr_mem)[i] = list_strdup(list, name); - if ((result->gr_mem)[i] == NULL) { - return NULL; + if (i == gr->num_gr_mem) { + break; } + result->gr_mem[i] = strdup(name); i++; } /* Terminate list */ - (result->gr_mem)[i] = NULL; + result->gr_mem[i] = NULL; return result; } @@ -220,13 +265,12 @@ static struct group *fill_grent(struct mem_list **list, struct winbindd_gr *gr, /* take a group id and return a filled struct group */ static struct group *wb_aix_getgrgid(gid_t gid) { - static struct mem_list *list; struct winbindd_response response; struct winbindd_request request; struct group *grp; NSS_STATUS ret; - list_destory(&list); + logit("getgrgid %d\n", gid); ZERO_STRUCT(response); ZERO_STRUCT(request); @@ -235,9 +279,11 @@ static struct group *wb_aix_getgrgid(gid_t gid) ret = winbindd_request(WINBINDD_GETGRGID, &request, &response); + logit("getgrgid ret=%d\n", ret); + HANDLE_ERRORS(ret); - grp = fill_grent(&list, &response.data.gr, response.extra_data); + grp = fill_grent(&response.data.gr, response.extra_data); free_response(&response); @@ -247,28 +293,27 @@ static struct group *wb_aix_getgrgid(gid_t gid) /* take a group name and return a filled struct group */ static struct group *wb_aix_getgrnam(const char *name) { - static struct mem_list *list; struct winbindd_response response; struct winbindd_request request; NSS_STATUS ret; struct group *grp; - list_destory(&list); + if (*name == WB_AIX_ENCODED) { + return wb_aix_getgrgid(decode_id(name)); + } + + logit("getgrnam '%s'\n", name); ZERO_STRUCT(response); ZERO_STRUCT(request); - if (strlen(name)+1 > sizeof(request.data.groupname)) { - errno = EINVAL; - return NULL; - } - strcpy(request.data.groupname, name); + STRCPY_RETNULL(request.data.groupname, name); ret = winbindd_request(WINBINDD_GETGRNAM, &request, &response); HANDLE_ERRORS(ret); - grp = fill_grent(&list, &response.data.gr, response.extra_data); + grp = fill_grent(&response.data.gr, response.extra_data); free_response(&response); @@ -276,11 +321,25 @@ static struct group *wb_aix_getgrnam(const char *name) } +/* this call doesn't have to fill in the gr_mem, but we do anyway + for simplicity */ +static struct group *wb_aix_getgracct(void *id, int type) +{ + if (type == 1) { + return wb_aix_getgrnam((char *)id); + } + if (type == 0) { + return wb_aix_getgrgid(*(int *)id); + } + errno = EINVAL; + return NULL; +} + + /* take a username and return a string containing a comma-separated list of group id numbers to which the user belongs */ static char *wb_aix_getgrset(char *user) { - static struct mem_list *list; struct winbindd_response response; struct winbindd_request request; NSS_STATUS ret; @@ -288,14 +347,23 @@ static char *wb_aix_getgrset(char *user) char *tmpbuf; int num_gids; gid_t *gid_list; + char *r_user = user; - list_destory(&list); + if (*user == WB_AIX_ENCODED) { + r_user = decode_user(r_user); + if (!r_user) { + errno = ENOENT; + return NULL; + } + } - if (strlen(user)+1 > sizeof(request.data.username)) { - errno = EINVAL; - return NULL; + logit("getgrset '%s'\n", r_user); + + STRCPY_RETNULL(request.data.username, r_user); + + if (*user == WB_AIX_ENCODED) { + free(r_user); } - strcpy(request.data.username, user); ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response); @@ -305,7 +373,7 @@ static char *wb_aix_getgrset(char *user) gid_list = (gid_t *)response.extra_data; /* allocate a space large enough to contruct the string */ - tmpbuf = list_alloc(&list, num_gids*12); + tmpbuf = malloc(num_gids*12); if (!tmpbuf) { return NULL; } @@ -324,13 +392,13 @@ static char *wb_aix_getgrset(char *user) /* take a uid and return a filled struct passwd */ static struct passwd *wb_aix_getpwuid(uid_t uid) { - static struct mem_list *list; struct winbindd_response response; struct winbindd_request request; NSS_STATUS ret; + struct passwd *pwd; + + logit("getpwuid '%d'\n", uid); - list_destory(&list); - ZERO_STRUCT(response); ZERO_STRUCT(request); @@ -340,49 +408,611 @@ static struct passwd *wb_aix_getpwuid(uid_t uid) HANDLE_ERRORS(ret); - return fill_pwent(&list, &response.data.pw); + pwd = fill_pwent(&response.data.pw); + + free_response(&response); + + logit("getpwuid gave ptr %p\n", pwd); + + return pwd; } /* take a username and return a filled struct passwd */ static struct passwd *wb_aix_getpwnam(const char *name) { - static struct mem_list *list; struct winbindd_response response; struct winbindd_request request; NSS_STATUS ret; + struct passwd *pwd; + + if (*name == WB_AIX_ENCODED) { + return wb_aix_getpwuid(decode_id(name)); + } + + logit("getpwnam '%s'\n", name); - list_destory(&list); - ZERO_STRUCT(response); ZERO_STRUCT(request); - if (strlen(name)+1 > sizeof(request.data.username)) { + STRCPY_RETNULL(request.data.username, name); + + ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response); + + HANDLE_ERRORS(ret); + + pwd = fill_pwent(&response.data.pw); + + free_response(&response); + + logit("getpwnam gave ptr %p\n", pwd); + + return pwd; +} + +/* + list users +*/ +static int wb_aix_lsuser(char *attributes[], attrval_t results[], int size) +{ + NSS_STATUS ret; + struct winbindd_request request; + struct winbindd_response response; + int len; + char *s; + + if (size != 1 || strcmp(attributes[0], S_USERS) != 0) { + logit("invalid lsuser op\n"); errno = EINVAL; - return NULL; + return -1; } - strcpy(request.data.username, name); + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + ret = winbindd_request(WINBINDD_LIST_USERS, &request, &response); + if (ret != 0) { + errno = EINVAL; + return -1; + } - ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response); + len = strlen(response.extra_data); - HANDLE_ERRORS(ret); + s = malloc(len+2); + if (!s) { + free_response(&response); + errno = ENOMEM; + return -1; + } + + memcpy(s, response.extra_data, len+1); + + replace_commas(s); + + results[0].attr_un.au_char = s; + results[0].attr_flag = 0; + + free_response(&response); + + return 0; +} + + +/* + list groups +*/ +static int wb_aix_lsgroup(char *attributes[], attrval_t results[], int size) +{ + NSS_STATUS ret; + struct winbindd_request request; + struct winbindd_response response; + int len; + char *s; + + if (size != 1 || strcmp(attributes[0], S_GROUPS) != 0) { + logit("invalid lsgroup op\n"); + errno = EINVAL; + return -1; + } + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + ret = winbindd_request(WINBINDD_LIST_GROUPS, &request, &response); + if (ret != 0) { + errno = EINVAL; + return -1; + } + + len = strlen(response.extra_data); + + s = malloc(len+2); + if (!s) { + free_response(&response); + errno = ENOMEM; + return -1; + } + + memcpy(s, response.extra_data, len+1); + + replace_commas(s); + + results[0].attr_un.au_char = s; + results[0].attr_flag = 0; + + free_response(&response); - return fill_pwent(&list, &response.data.pw); + return 0; +} + + +static attrval_t pwd_to_group(struct passwd *pwd) +{ + attrval_t r; + struct group *grp = wb_aix_getgrgid(pwd->pw_gid); + + if (!grp) { + r.attr_flag = EINVAL; + } else { + r.attr_flag = 0; + r.attr_un.au_char = strdup(grp->gr_name); + free_grp(grp); + } + + return r; +} + +static attrval_t pwd_to_groupsids(struct passwd *pwd) +{ + attrval_t r; + char *s, *p; + + s = wb_aix_getgrset(pwd->pw_name); + if (!s) { + r.attr_flag = EINVAL; + return r; + } + + p = malloc(strlen(s)+2); + if (!p) { + r.attr_flag = ENOMEM; + return r; + } + + strcpy(p, s); + replace_commas(p); + free(s); + + r.attr_un.au_char = p; + + return r; +} + +static attrval_t pwd_to_sid(struct passwd *pwd) +{ + struct winbindd_request request; + struct winbindd_response response; + attrval_t r; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + request.data.uid = pwd->pw_uid; + + if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) != + NSS_STATUS_SUCCESS) { + r.attr_flag = ENOENT; + } else { + r.attr_flag = 0; + r.attr_un.au_char = strdup(response.data.sid.sid); + } + + return r; +} + +static int wb_aix_user_attrib(const char *key, char *attributes[], + attrval_t results[], int size) +{ + struct passwd *pwd; + int i; + + pwd = wb_aix_getpwnam(key); + if (!pwd) { + errno = ENOENT; + return -1; + } + + for (i=0;ipw_uid; + } else if (strcmp(attributes[i], S_PWD) == 0) { + results[i].attr_un.au_char = strdup(pwd->pw_passwd); + } else if (strcmp(attributes[i], S_HOME) == 0) { + results[i].attr_un.au_char = strdup(pwd->pw_dir); + } else if (strcmp(attributes[0], S_SHELL) == 0) { + results[i].attr_un.au_char = strdup(pwd->pw_shell); + } else if (strcmp(attributes[0], S_REGISTRY) == 0) { + results[i].attr_un.au_char = strdup("WINBIND"); + } else if (strcmp(attributes[0], S_GECOS) == 0) { + results[i].attr_un.au_char = strdup(pwd->pw_gecos); + } else if (strcmp(attributes[0], S_PGRP) == 0) { + results[i] = pwd_to_group(pwd); + } else if (strcmp(attributes[0], S_GECOS) == 0) { + results[i].attr_un.au_char = strdup(pwd->pw_gecos); + } else if (strcmp(attributes[0], S_GROUPSIDS) == 0) { + results[i] = pwd_to_groupsids(pwd); + } else if (strcmp(attributes[0], "SID") == 0) { + results[i] = pwd_to_sid(pwd); + } else { + logit("Unknown user attribute '%s'\n", attributes[i]); + results[i].attr_flag = EINVAL; + } + } + + free_pwd(pwd); + + return 0; +} + +static int wb_aix_group_attrib(const char *key, char *attributes[], + attrval_t results[], int size) +{ + struct group *grp; + int i; + + grp = wb_aix_getgrnam(key); + if (!grp) { + errno = ENOENT; + return -1; + } + + for (i=0;igr_passwd); + } else if (strcmp(attributes[i], S_ID) == 0) { + results[i].attr_un.au_int = grp->gr_gid; + } else { + logit("Unknown group attribute '%s'\n", attributes[i]); + results[i].attr_flag = EINVAL; + } + } + + free_grp(grp); + + return 0; } + +/* + called for user/group enumerations +*/ +static int wb_aix_getentry(char *key, char *table, char *attributes[], + attrval_t results[], int size) +{ + logit("Got getentry with key='%s' table='%s' size=%d attributes[0]='%s'\n", + key, table, size, attributes[0]); + + if (strcmp(key, "ALL") == 0 && + strcmp(table, "user") == 0) { + return wb_aix_lsuser(attributes, results, size); + } + + if (strcmp(key, "ALL") == 0 && + strcmp(table, "group") == 0) { + return wb_aix_lsgroup(attributes, results, size); + } + + if (strcmp(table, "user") == 0) { + return wb_aix_user_attrib(key, attributes, results, size); + } + + if (strcmp(table, "group") == 0) { + return wb_aix_group_attrib(key, attributes, results, size); + } + + logit("Unknown getentry operation key='%s' table='%s'\n", key, table); + + errno = ENOSYS; + return -1; +} + + + +/* + called to start the backend +*/ +static void *wb_aix_open(const char *name, const char *domain, int mode, char *options) +{ + if (strstr(options, "debug")) { + debug_enabled = 1; + } + logit("open name='%s' mode=%d domain='%s' options='%s'\n", name, domain, + mode, options); + return NULL; +} + +static void wb_aix_close(void *token) +{ + logit("close\n"); + return; +} + +/* + return a list of additional attributes supported by the backend +*/ +static attrlist_t **wb_aix_attrlist(void) +{ + attrlist_t **ret; + logit("method attrlist called\n"); + ret = malloc(2*sizeof(attrlist_t *) + sizeof(attrlist_t)); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret[0] = (attrlist_t *)(ret+2); + + /* just one extra attribute - the windows SID */ + ret[0]->al_name = strdup("SID"); + ret[0]->al_flags = AL_USERATTR; + ret[0]->al_type = SEC_CHAR; + ret[1] = NULL; + + return ret; +} + + +/* + turn a long username into a short one. Needed to cope with the 8 char + username limit in AIX 5.2 and below +*/ +static int wb_aix_normalize(char *longname, char *shortname) +{ + struct passwd *pwd; + + logit("normalize '%s'\n", longname); + + /* automatically cope with AIX 5.3 with longer usernames + when it comes out */ + if (S_NAMELEN > strlen(longname)) { + strcpy(shortname, longname); + return 1; + } + + pwd = wb_aix_getpwnam(longname); + if (!pwd) { + errno = ENOENT; + return 0; + } + + sprintf(shortname, "%c%07u", WB_AIX_ENCODED, pwd->pw_uid); + + free_pwd(pwd); + + return 1; +} + + +/* + authenticate a user + */ +static int wb_aix_authenticate(char *user, char *pass, + int *reenter, char **message) +{ + struct winbindd_request request; + struct winbindd_response response; + NSS_STATUS result; + char *r_user = user; + + logit("authenticate '%s' response='%s'\n", user, pass); + + *reenter = 0; + *message = NULL; + + /* Send off request */ + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + if (*user == WB_AIX_ENCODED) { + r_user = decode_user(r_user); + if (!r_user) { + return AUTH_NOTFOUND; + } + } + + STRCPY_RET(request.data.auth.user, r_user); + STRCPY_RET(request.data.auth.pass, pass); + + if (*user == WB_AIX_ENCODED) { + free(r_user); + } + + result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response); + + free_response(&response); + + logit("auth result %d for '%s'\n", result, user); + + if (result == NSS_STATUS_SUCCESS) { + errno = 0; + return AUTH_SUCCESS; + } + + return AUTH_FAILURE; +} + + +/* + change a user password +*/ +static int wb_aix_chpass(char *user, char *oldpass, char *newpass, char **message) +{ + struct winbindd_request request; + struct winbindd_response response; + NSS_STATUS result; + char *r_user = user; + + if (*user == WB_AIX_ENCODED) { + r_user = decode_user(r_user); + if (!r_user) { + errno = ENOENT; + return -1; + } + } + + logit("chpass '%s' old='%s' new='%s'\n", r_user, oldpass, newpass); + + *message = NULL; + + /* Send off request */ + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + STRCPY_RET(request.data.chauthtok.user, r_user); + STRCPY_RET(request.data.chauthtok.oldpass, oldpass); + STRCPY_RET(request.data.chauthtok.newpass, newpass); + + if (*user == WB_AIX_ENCODED) { + free(r_user); + } + + result = winbindd_request(WINBINDD_PAM_CHAUTHTOK, &request, &response); + + free_response(&response); + + if (result == NSS_STATUS_SUCCESS) { + errno = 0; + return 0; + } + + errno = EINVAL; + return -1; +} + +/* + don't do any password strength testing for now +*/ +static int wb_aix_passwdrestrictions(char *user, char *newpass, char *oldpass, + char **message) +{ + logit("passwdresrictions called for '%s'\n", user); + return 0; +} + + +static int wb_aix_passwdexpired(char *user, char **message) +{ + logit("passwdexpired '%s'\n", user); + /* we should check the account bits here */ + return 0; +} + + +/* + we can't return a crypt() password +*/ +static char *wb_aix_getpasswd(char *user) +{ + logit("getpasswd '%s'\n", user); + errno = ENOSYS; + return NULL; +} + +/* + this is called to update things like the last login time. We don't + currently pass this onto the DC +*/ +static int wb_aix_putentry(char *key, char *table, char *attributes[], + attrval_t values[], int size) +{ + logit("putentry key='%s' table='%s' attrib='%s'\n", + key, table, size>=1?attributes[0]:""); + errno = ENOSYS; + return -1; +} + +static int wb_aix_commit(char *key, char *table) +{ + logit("commit key='%s' table='%s'\n"); + errno = ENOSYS; + return -1; +} + +static int wb_aix_getgrusers(char *group, void *result, int type, int *size) +{ + logit("getgrusers group='%s'\n", group); + errno = ENOSYS; + return -1; +} + + +#define DECL_METHOD(x) \ +int method_ ## x(void) \ +{ \ + logit("UNIMPLEMENTED METHOD '%s'\n", #x); \ + errno = EINVAL; \ + return -1; \ +} + +#if LOG_UNIMPLEMENTED_CALLS +DECL_METHOD(delgroup); +DECL_METHOD(deluser); +DECL_METHOD(newgroup); +DECL_METHOD(newuser); +DECL_METHOD(putgrent); +DECL_METHOD(putgrusers); +DECL_METHOD(putpwent); +DECL_METHOD(lock); +DECL_METHOD(unlock); +DECL_METHOD(getcred); +DECL_METHOD(setcred); +DECL_METHOD(deletecred); +#endif + int wb_aix_init(struct secmethod_table *methods) { ZERO_STRUCTP(methods); - /* identification methods, this is the minimum requried for a - working module */ - - methods->method_getgrgid = wb_aix_getgrgid; - methods->method_getgrnam = wb_aix_getgrnam; - methods->method_getgrset = wb_aix_getgrset; - methods->method_getpwnam = wb_aix_getpwnam; - methods->method_getpwuid = wb_aix_getpwuid; + methods->method_version = SECMETHOD_VERSION_520; + + methods->method_getgrgid = wb_aix_getgrgid; + methods->method_getgrnam = wb_aix_getgrnam; + methods->method_getgrset = wb_aix_getgrset; + methods->method_getpwnam = wb_aix_getpwnam; + methods->method_getpwuid = wb_aix_getpwuid; + methods->method_getentry = wb_aix_getentry; + methods->method_open = wb_aix_open; + methods->method_close = wb_aix_close; + methods->method_normalize = wb_aix_normalize; + methods->method_passwdexpired = wb_aix_passwdexpired; + methods->method_putentry = wb_aix_putentry; + methods->method_getpasswd = wb_aix_getpasswd; + methods->method_authenticate = wb_aix_authenticate; + methods->method_commit = wb_aix_commit; + methods->method_chpass = wb_aix_chpass; + methods->method_passwdrestrictions = wb_aix_passwdrestrictions; + methods->method_getgracct = wb_aix_getgracct; + methods->method_getgrusers = wb_aix_getgrusers; + methods->method_attrlist = wb_aix_attrlist; + +#if LOG_UNIMPLEMENTED_CALLS + methods->method_delgroup = method_delgroup; + methods->method_deluser = method_deluser; + methods->method_newgroup = method_newgroup; + methods->method_newuser = method_newuser; + methods->method_putgrent = method_putgrent; + methods->method_putgrusers = method_putgrusers; + methods->method_putpwent = method_putpwent; + methods->method_lock = method_lock; + methods->method_unlock = method_unlock; + methods->method_getcred = method_getcred; + methods->method_setcred = method_setcred; + methods->method_deletecred = method_deletecred; +#endif return AUTH_SUCCESS; } -- cgit From 147e585748c5f720547ebe5adce580585dcd7928 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 29 Jan 2004 08:48:50 +0000 Subject: This should cure the problem with gums not compiling. (This used to be commit 428504b5508e9e0f9cbc0dc8041f25f06de52f88) --- source3/sam/gums_api.c | 308 ++++++++++++++++++++++++++++++------------------- 1 file changed, 188 insertions(+), 120 deletions(-) diff --git a/source3/sam/gums_api.c b/source3/sam/gums_api.c index a76aed18fd..f90cbbc951 100644 --- a/source3/sam/gums_api.c +++ b/source3/sam/gums_api.c @@ -24,18 +24,38 @@ NTSTATUS gums_create_object(GUMS_OBJECT **obj, uint32 type) { - TALLOC_CTX *mem_ctx = talloc_init("gums_create_object"); + TALLOC_CTX *mem_ctx; GUMS_OBJECT *go; NTSTATUS ret; - + + mem_ctx = talloc_init("gums_create_object"); + if (!mem_ctx) { + DEBUG(0, ("gums_create_object: Out of memory!\n")); + *obj = NULL; + return NT_STATUS_NO_MEMORY; + } + go = talloc_zero(mem_ctx, sizeof(GUMS_OBJECT)); + if (!go) { + DEBUG(0, ("gums_create_object: Out of memory!\n")); + talloc_destroy(mem_ctx); + *obj = NULL; + return NT_STATUS_NO_MEMORY; + } + go->mem_ctx = mem_ctx; go->type = type; go->version = GUMS_OBJECT_VERSION; switch(type) { case GUMS_OBJ_DOMAIN: - go->data.domain = (GUMS_DOMAIN *)talloc_zero(mem_ctx, sizeof(GUMS_DOMAIN)); + go->domain = (GUMS_DOMAIN *)talloc_zero(mem_ctx, sizeof(GUMS_DOMAIN)); + if (!(go->domain)) { + ret = NT_STATUS_NO_MEMORY; + DEBUG(0, ("gums_create_object: Out of memory!\n")); + goto error; + } + break; /* @@ -44,16 +64,26 @@ NTSTATUS gums_create_object(GUMS_OBJECT **obj, uint32 type) case GUMS_OBJ_DOMAIN_TRUST: */ case GUMS_OBJ_NORMAL_USER: - go->data.user = (GUMS_USER *)talloc_zero(mem_ctx, sizeof(GUMS_USER)); + go->user = (GUMS_USER *)talloc_zero(mem_ctx, sizeof(GUMS_USER)); + if (!(go->user)) { + ret = NT_STATUS_NO_MEMORY; + DEBUG(0, ("gums_create_object: Out of memory!\n")); + goto error; + } + gums_set_user_acct_ctrl(go, ACB_NORMAL); + gums_set_user_hours(go, 0, NULL); + break; case GUMS_OBJ_GROUP: case GUMS_OBJ_ALIAS: - go->data.group = (GUMS_GROUP *)talloc_zero(mem_ctx, sizeof(GUMS_GROUP)); - break; + go->group = (GUMS_GROUP *)talloc_zero(mem_ctx, sizeof(GUMS_GROUP)); + if (!(go->group)) { + ret = NT_STATUS_NO_MEMORY; + DEBUG(0, ("gums_create_object: Out of memory!\n")); + goto error; + } - case GUMS_OBJ_PRIVILEGE: - go->data.priv = (GUMS_PRIVILEGE *)talloc_zero(mem_ctx, sizeof(GUMS_PRIVILEGE)); break; default: @@ -62,18 +92,6 @@ NTSTATUS gums_create_object(GUMS_OBJECT **obj, uint32 type) goto error; } - if (!(go->data.user)) { - ret = NT_STATUS_NO_MEMORY; - DEBUG(0, ("gums_create_object: Out of memory!\n")); - goto error; - } - - switch(type) { - case GUMS_OBJ_NORMAL_USER: - gums_set_user_acct_ctrl(go, ACB_NORMAL); - gums_set_user_hours(go, 0, NULL); - } - *obj = go; return NT_STATUS_OK; @@ -83,6 +101,33 @@ error: return ret; } +NTSTATUS gums_create_privilege(GUMS_PRIVILEGE **priv) +{ + TALLOC_CTX *mem_ctx; + GUMS_PRIVILEGE *pri; + + mem_ctx = talloc_init("gums_create_privilege"); + if (!mem_ctx) { + DEBUG(0, ("gums_create_privilege: Out of memory!\n")); + *priv = NULL; + return NT_STATUS_NO_MEMORY; + } + + pri = talloc_zero(mem_ctx, sizeof(GUMS_PRIVILEGE)); + if (!pri) { + DEBUG(0, ("gums_create_privilege: Out of memory!\n")); + talloc_destroy(mem_ctx); + *priv = NULL; + return NT_STATUS_NO_MEMORY; + } + + pri->mem_ctx = mem_ctx; + pri->version = GUMS_PRIVILEGE_VERSION; + + *priv = pri; + return NT_STATUS_OK; +} + NTSTATUS gums_destroy_object(GUMS_OBJECT **obj) { if (!obj || !(*obj)) @@ -95,6 +140,18 @@ NTSTATUS gums_destroy_object(GUMS_OBJECT **obj) return NT_STATUS_OK; } +NTSTATUS gums_destroy_privilege(GUMS_PRIVILEGE **priv) +{ + if (!priv || !(*priv)) + return NT_STATUS_INVALID_PARAMETER; + + if ((*priv)->mem_ctx) + talloc_destroy((*priv)->mem_ctx); + *priv = NULL; + + return NT_STATUS_OK; +} + void gums_reset_object(GUMS_OBJECT *go) { go->seq_num = 0; @@ -104,7 +161,7 @@ void gums_reset_object(GUMS_OBJECT *go) switch(go->type) { case GUMS_OBJ_DOMAIN: - memset(go->data.domain, 0, sizeof(GUMS_DOMAIN)); + memset(go->domain, 0, sizeof(GUMS_DOMAIN)); break; /* @@ -113,17 +170,13 @@ void gums_reset_object(GUMS_OBJECT *go) case GUMS_OBJ_DOMAIN_TRUST: */ case GUMS_OBJ_NORMAL_USER: - memset(go->data.user, 0, sizeof(GUMS_USER)); + memset(go->user, 0, sizeof(GUMS_USER)); gums_set_user_acct_ctrl(go, ACB_NORMAL); break; case GUMS_OBJ_GROUP: case GUMS_OBJ_ALIAS: - memset(go->data.group, 0, sizeof(GUMS_GROUP)); - break; - - case GUMS_OBJ_PRIVILEGE: - memset(go->data.priv, 0, sizeof(GUMS_PRIVILEGE)); + memset(go->group, 0, sizeof(GUMS_GROUP)); break; default: @@ -261,7 +314,7 @@ uint32 gums_get_domain_next_rid(const GUMS_OBJECT *obj) if (obj->type != GUMS_OBJ_DOMAIN) return -1; - return obj->data.domain->next_rid; + return obj->domain->next_rid; } NTSTATUS gums_set_domain_next_rid(GUMS_OBJECT *obj, uint32 rid) @@ -272,7 +325,7 @@ NTSTATUS gums_set_domain_next_rid(GUMS_OBJECT *obj, uint32 rid) if (obj->type != GUMS_OBJ_DOMAIN) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.domain->next_rid = rid; + obj->domain->next_rid = rid; return NT_STATUS_OK; } @@ -283,7 +336,7 @@ const DOM_SID *gums_get_user_pri_group(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return NULL; - return obj->data.user->group_sid; + return obj->user->group_sid; } const DATA_BLOB gums_get_user_nt_pwd(const GUMS_OBJECT *obj) @@ -293,10 +346,10 @@ const DATA_BLOB gums_get_user_nt_pwd(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return data_blob(NULL, 0); - smbpasswd_sethexpwd(p, (unsigned char *)(obj->data.user->nt_pw.data), 0); + smbpasswd_sethexpwd(p, (unsigned char *)(obj->user->nt_pw.data), 0); DEBUG(100, ("Reading NT Password=[%s]\n", p)); - return obj->data.user->nt_pw; + return obj->user->nt_pw; } const DATA_BLOB gums_get_user_lm_pwd(const GUMS_OBJECT *obj) @@ -306,10 +359,10 @@ const DATA_BLOB gums_get_user_lm_pwd(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return data_blob(NULL, 0); - smbpasswd_sethexpwd(p, (unsigned char *)(obj->data.user->lm_pw.data), 0); + smbpasswd_sethexpwd(p, (unsigned char *)(obj->user->lm_pw.data), 0); DEBUG(100, ("Reading LM Password=[%s]\n", p)); - return obj->data.user->lm_pw; + return obj->user->lm_pw; } const char *gums_get_user_fullname(const GUMS_OBJECT *obj) @@ -317,7 +370,7 @@ const char *gums_get_user_fullname(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return NULL; - return obj->data.user->full_name; + return obj->user->full_name; } const char *gums_get_user_homedir(const GUMS_OBJECT *obj) @@ -325,7 +378,7 @@ const char *gums_get_user_homedir(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return NULL; - return obj->data.user->home_dir; + return obj->user->home_dir; } const char *gums_get_user_dir_drive(const GUMS_OBJECT *obj) @@ -333,7 +386,7 @@ const char *gums_get_user_dir_drive(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return NULL; - return obj->data.user->dir_drive; + return obj->user->dir_drive; } const char *gums_get_user_profile_path(const GUMS_OBJECT *obj) @@ -341,7 +394,7 @@ const char *gums_get_user_profile_path(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return NULL; - return obj->data.user->profile_path; + return obj->user->profile_path; } const char *gums_get_user_logon_script(const GUMS_OBJECT *obj) @@ -349,7 +402,7 @@ const char *gums_get_user_logon_script(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return NULL; - return obj->data.user->logon_script; + return obj->user->logon_script; } const char *gums_get_user_workstations(const GUMS_OBJECT *obj) @@ -357,7 +410,7 @@ const char *gums_get_user_workstations(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return NULL; - return obj->data.user->workstations; + return obj->user->workstations; } const char *gums_get_user_unknown_str(const GUMS_OBJECT *obj) @@ -365,7 +418,7 @@ const char *gums_get_user_unknown_str(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return NULL; - return obj->data.user->unknown_str; + return obj->user->unknown_str; } const char *gums_get_user_munged_dial(const GUMS_OBJECT *obj) @@ -373,7 +426,7 @@ const char *gums_get_user_munged_dial(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return NULL; - return obj->data.user->munged_dial; + return obj->user->munged_dial; } NTTIME gums_get_user_logon_time(const GUMS_OBJECT *obj) @@ -384,7 +437,7 @@ NTTIME gums_get_user_logon_time(const GUMS_OBJECT *obj) return null_time; } - return obj->data.user->logon_time; + return obj->user->logon_time; } NTTIME gums_get_user_logoff_time(const GUMS_OBJECT *obj) @@ -395,7 +448,7 @@ NTTIME gums_get_user_logoff_time(const GUMS_OBJECT *obj) return null_time; } - return obj->data.user->logoff_time; + return obj->user->logoff_time; } NTTIME gums_get_user_kickoff_time(const GUMS_OBJECT *obj) @@ -406,7 +459,7 @@ NTTIME gums_get_user_kickoff_time(const GUMS_OBJECT *obj) return null_time; } - return obj->data.user->kickoff_time; + return obj->user->kickoff_time; } NTTIME gums_get_user_pass_last_set_time(const GUMS_OBJECT *obj) @@ -417,7 +470,7 @@ NTTIME gums_get_user_pass_last_set_time(const GUMS_OBJECT *obj) return null_time; } - return obj->data.user->pass_last_set_time; + return obj->user->pass_last_set_time; } NTTIME gums_get_user_pass_can_change_time(const GUMS_OBJECT *obj) @@ -428,7 +481,7 @@ NTTIME gums_get_user_pass_can_change_time(const GUMS_OBJECT *obj) return null_time; } - return obj->data.user->pass_can_change_time; + return obj->user->pass_can_change_time; } NTTIME gums_get_user_pass_must_change_time(const GUMS_OBJECT *obj) @@ -439,7 +492,7 @@ NTTIME gums_get_user_pass_must_change_time(const GUMS_OBJECT *obj) return null_time; } - return obj->data.user->pass_must_change_time; + return obj->user->pass_must_change_time; } uint16 gums_get_user_acct_ctrl(const GUMS_OBJECT *obj) @@ -447,7 +500,7 @@ uint16 gums_get_user_acct_ctrl(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return 0; - return obj->data.user->acct_ctrl; + return obj->user->acct_ctrl; } uint16 gums_get_user_logon_divs(const GUMS_OBJECT *obj) @@ -455,7 +508,7 @@ uint16 gums_get_user_logon_divs(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return 0; - return obj->data.user->logon_divs; + return obj->user->logon_divs; } uint32 gums_get_user_hours_len(const GUMS_OBJECT *obj) @@ -463,7 +516,7 @@ uint32 gums_get_user_hours_len(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return 0; - return obj->data.user->hours_len; + return obj->user->hours_len; } const uint8 *gums_get_user_hours(const GUMS_OBJECT *obj) @@ -471,7 +524,15 @@ const uint8 *gums_get_user_hours(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return NULL; - return obj->data.user->hours; + return obj->user->hours; +} + +uint32 gums_get_user_unknown_3(const GUMS_OBJECT *obj) +{ + if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) + return 0; + + return obj->user->unknown_3; } uint16 gums_get_user_bad_password_count(const GUMS_OBJECT *obj) @@ -479,7 +540,7 @@ uint16 gums_get_user_bad_password_count(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return 0; - return obj->data.user->bad_password_count; + return obj->user->bad_password_count; } uint16 gums_get_user_logon_count(const GUMS_OBJECT *obj) @@ -487,7 +548,7 @@ uint16 gums_get_user_logon_count(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return 0; - return obj->data.user->logon_count; + return obj->user->logon_count; } uint32 gums_get_user_unknown_6(const GUMS_OBJECT *obj) @@ -495,7 +556,7 @@ uint32 gums_get_user_unknown_6(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return 0; - return obj->data.user->unknown_6; + return obj->user->unknown_6; } NTSTATUS gums_set_user_pri_group(GUMS_OBJECT *obj, const DOM_SID *sid) @@ -506,8 +567,8 @@ NTSTATUS gums_set_user_pri_group(GUMS_OBJECT *obj, const DOM_SID *sid) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->group_sid = sid_dup_talloc(obj->mem_ctx, sid); - if (!(obj->data.user->group_sid)) return NT_STATUS_NO_MEMORY; + obj->user->group_sid = sid_dup_talloc(obj->mem_ctx, sid); + if (!(obj->user->group_sid)) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } @@ -522,7 +583,7 @@ NTSTATUS gums_set_user_nt_pwd(GUMS_OBJECT *obj, const DATA_BLOB nt_pwd) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->nt_pw = data_blob_talloc(obj->mem_ctx, nt_pwd.data, nt_pwd.length); + obj->user->nt_pw = data_blob_talloc(obj->mem_ctx, nt_pwd.data, nt_pwd.length); memcpy(r, nt_pwd.data, 16); smbpasswd_sethexpwd(p, r, 0); @@ -542,7 +603,7 @@ NTSTATUS gums_set_user_lm_pwd(GUMS_OBJECT *obj, const DATA_BLOB lm_pwd) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->lm_pw = data_blob_talloc(obj->mem_ctx, lm_pwd.data, lm_pwd.length); + obj->user->lm_pw = data_blob_talloc(obj->mem_ctx, lm_pwd.data, lm_pwd.length); memcpy(r, lm_pwd.data, 16); smbpasswd_sethexpwd(p, r, 0); @@ -559,8 +620,8 @@ NTSTATUS gums_set_user_fullname(GUMS_OBJECT *obj, const char *fullname) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->full_name = (char *)talloc_strdup(obj->mem_ctx, fullname); - if (!(obj->data.user->full_name)) return NT_STATUS_NO_MEMORY; + obj->user->full_name = (char *)talloc_strdup(obj->mem_ctx, fullname); + if (!(obj->user->full_name)) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } @@ -572,8 +633,8 @@ NTSTATUS gums_set_user_homedir(GUMS_OBJECT *obj, const char *homedir) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->home_dir = (char *)talloc_strdup(obj->mem_ctx, homedir); - if (!(obj->data.user->home_dir)) return NT_STATUS_NO_MEMORY; + obj->user->home_dir = (char *)talloc_strdup(obj->mem_ctx, homedir); + if (!(obj->user->home_dir)) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } @@ -585,8 +646,8 @@ NTSTATUS gums_set_user_dir_drive(GUMS_OBJECT *obj, const char *dir_drive) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->dir_drive = (char *)talloc_strdup(obj->mem_ctx, dir_drive); - if (!(obj->data.user->dir_drive)) return NT_STATUS_NO_MEMORY; + obj->user->dir_drive = (char *)talloc_strdup(obj->mem_ctx, dir_drive); + if (!(obj->user->dir_drive)) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } @@ -598,8 +659,8 @@ NTSTATUS gums_set_user_logon_script(GUMS_OBJECT *obj, const char *logon_script) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->logon_script = (char *)talloc_strdup(obj->mem_ctx, logon_script); - if (!(obj->data.user->logon_script)) return NT_STATUS_NO_MEMORY; + obj->user->logon_script = (char *)talloc_strdup(obj->mem_ctx, logon_script); + if (!(obj->user->logon_script)) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } @@ -611,8 +672,8 @@ NTSTATUS gums_set_user_profile_path(GUMS_OBJECT *obj, const char *profile_path) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->profile_path = (char *)talloc_strdup(obj->mem_ctx, profile_path); - if (!(obj->data.user->profile_path)) return NT_STATUS_NO_MEMORY; + obj->user->profile_path = (char *)talloc_strdup(obj->mem_ctx, profile_path); + if (!(obj->user->profile_path)) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } @@ -624,8 +685,8 @@ NTSTATUS gums_set_user_workstations(GUMS_OBJECT *obj, const char *workstations) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->workstations = (char *)talloc_strdup(obj->mem_ctx, workstations); - if (!(obj->data.user->workstations)) return NT_STATUS_NO_MEMORY; + obj->user->workstations = (char *)talloc_strdup(obj->mem_ctx, workstations); + if (!(obj->user->workstations)) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } @@ -637,8 +698,8 @@ NTSTATUS gums_set_user_unknown_str(GUMS_OBJECT *obj, const char *unknown_str) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->unknown_str = (char *)talloc_strdup(obj->mem_ctx, unknown_str); - if (!(obj->data.user->unknown_str)) return NT_STATUS_NO_MEMORY; + obj->user->unknown_str = (char *)talloc_strdup(obj->mem_ctx, unknown_str); + if (!(obj->user->unknown_str)) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } @@ -650,8 +711,8 @@ NTSTATUS gums_set_user_munged_dial(GUMS_OBJECT *obj, const char *munged_dial) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->munged_dial = (char *)talloc_strdup(obj->mem_ctx, munged_dial); - if (!(obj->data.user->munged_dial)) return NT_STATUS_NO_MEMORY; + obj->user->munged_dial = (char *)talloc_strdup(obj->mem_ctx, munged_dial); + if (!(obj->user->munged_dial)) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } @@ -663,7 +724,7 @@ NTSTATUS gums_set_user_logon_time(GUMS_OBJECT *obj, NTTIME logon_time) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->logon_time = logon_time; + obj->user->logon_time = logon_time; return NT_STATUS_OK; } @@ -675,7 +736,7 @@ NTSTATUS gums_set_user_logoff_time(GUMS_OBJECT *obj, NTTIME logoff_time) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->logoff_time = logoff_time; + obj->user->logoff_time = logoff_time; return NT_STATUS_OK; } @@ -687,7 +748,7 @@ NTSTATUS gums_set_user_kickoff_time(GUMS_OBJECT *obj, NTTIME kickoff_time) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->kickoff_time = kickoff_time; + obj->user->kickoff_time = kickoff_time; return NT_STATUS_OK; } @@ -699,7 +760,7 @@ NTSTATUS gums_set_user_pass_last_set_time(GUMS_OBJECT *obj, NTTIME pass_last_set if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->pass_last_set_time = pass_last_set_time; + obj->user->pass_last_set_time = pass_last_set_time; return NT_STATUS_OK; } @@ -711,7 +772,7 @@ NTSTATUS gums_set_user_pass_can_change_time(GUMS_OBJECT *obj, NTTIME pass_can_ch if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->pass_can_change_time = pass_can_change_time; + obj->user->pass_can_change_time = pass_can_change_time; return NT_STATUS_OK; } @@ -723,7 +784,7 @@ NTSTATUS gums_set_user_pass_must_change_time(GUMS_OBJECT *obj, NTTIME pass_must_ if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->pass_must_change_time = pass_must_change_time; + obj->user->pass_must_change_time = pass_must_change_time; return NT_STATUS_OK; } @@ -735,7 +796,7 @@ NTSTATUS gums_set_user_acct_ctrl(GUMS_OBJECT *obj, uint16 acct_ctrl) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->acct_ctrl = acct_ctrl; + obj->user->acct_ctrl = acct_ctrl; return NT_STATUS_OK; } @@ -747,7 +808,7 @@ NTSTATUS gums_set_user_logon_divs(GUMS_OBJECT *obj, uint16 logon_divs) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->logon_divs = logon_divs; + obj->user->logon_divs = logon_divs; return NT_STATUS_OK; } @@ -759,19 +820,31 @@ NTSTATUS gums_set_user_hours(GUMS_OBJECT *obj, uint32 hours_len, const uint8 *ho if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->hours_len = hours_len; + obj->user->hours_len = hours_len; if (hours_len == 0) DEBUG(10, ("gums_set_user_hours: Warning, hours_len is zero!\n")); - obj->data.user->hours = (uint8 *)talloc(obj->mem_ctx, MAX_HOURS_LEN); - if (!(obj->data.user->hours)) + obj->user->hours = (uint8 *)talloc(obj->mem_ctx, MAX_HOURS_LEN); + if (!(obj->user->hours)) return NT_STATUS_NO_MEMORY; if (hours_len) - memcpy(obj->data.user->hours, hours, hours_len); + memcpy(obj->user->hours, hours, hours_len); return NT_STATUS_OK; } +NTSTATUS gums_set_user_unknown_3(GUMS_OBJECT *obj, uint32 unknown_3) +{ + if (!obj) + return NT_STATUS_INVALID_PARAMETER; + + if (obj->type != GUMS_OBJ_NORMAL_USER) + return NT_STATUS_OBJECT_TYPE_MISMATCH; + + obj->user->unknown_3 = unknown_3; + return NT_STATUS_OK; +} + NTSTATUS gums_set_user_bad_password_count(GUMS_OBJECT *obj, uint16 bad_password_count) { if (!obj) @@ -780,7 +853,7 @@ NTSTATUS gums_set_user_bad_password_count(GUMS_OBJECT *obj, uint16 bad_password_ if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->bad_password_count = bad_password_count; + obj->user->bad_password_count = bad_password_count; return NT_STATUS_OK; } @@ -792,7 +865,7 @@ NTSTATUS gums_set_user_logon_count(GUMS_OBJECT *obj, uint16 logon_count) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->logon_count = logon_count; + obj->user->logon_count = logon_count; return NT_STATUS_OK; } @@ -804,7 +877,7 @@ NTSTATUS gums_set_user_unknown_6(GUMS_OBJECT *obj, uint32 unknown_6) if (obj->type != GUMS_OBJ_NORMAL_USER) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.user->unknown_6 = unknown_6; + obj->user->unknown_6 = unknown_6; return NT_STATUS_OK; } @@ -817,8 +890,8 @@ const DOM_SID *gums_get_group_members(int *count, const GUMS_OBJECT *obj) return NULL; } - *count = obj->data.group->count; - return obj->data.group->members; + *count = obj->group->count; + return obj->group->members; } NTSTATUS gums_set_group_members(GUMS_OBJECT *obj, uint32 count, DOM_SID *members) @@ -832,22 +905,22 @@ NTSTATUS gums_set_group_members(GUMS_OBJECT *obj, uint32 count, DOM_SID *members obj->type != GUMS_OBJ_ALIAS) return NT_STATUS_OBJECT_TYPE_MISMATCH; - obj->data.group->count = count; + obj->group->count = count; if (count) { - obj->data.group->members = (DOM_SID *)talloc(obj->mem_ctx, count * sizeof(DOM_SID)); - if (!(obj->data.group->members)) { + obj->group->members = (DOM_SID *)talloc(obj->mem_ctx, count * sizeof(DOM_SID)); + if (!(obj->group->members)) { return NT_STATUS_NO_MEMORY; } n = 0; do { - sid_copy(&(obj->data.group->members[n]), &(members[n])); + sid_copy(&(obj->group->members[n]), &(members[n])); n++; } while (n < count); } else { - obj->data.group->members = 0; + obj->group->members = 0; } return NT_STATUS_OK; @@ -855,56 +928,51 @@ NTSTATUS gums_set_group_members(GUMS_OBJECT *obj, uint32 count, DOM_SID *members /* Privilege specific functions */ -const LUID_ATTR *gums_get_priv_luid_attr(const GUMS_OBJECT *obj) +const LUID_ATTR *gums_get_priv_luid_attr(const GUMS_PRIVILEGE *priv) { - if (!obj || obj->type != GUMS_OBJ_PRIVILEGE) + if (!priv) { return NULL; + } - return obj->data.priv->privilege; + return priv->privilege; } -const DOM_SID *gums_get_priv_members(int *count, const GUMS_OBJECT *obj) +const DOM_SID *gums_get_priv_members(int *count, const GUMS_PRIVILEGE *priv) { - if (!count || !obj || obj->type != GUMS_OBJ_PRIVILEGE) { + if (!count || !priv) { *count = -1; return NULL; } - *count = obj->data.priv->count; - return obj->data.priv->members; + *count = priv->count; + return priv->members; } -NTSTATUS gums_set_priv_luid_attr(GUMS_OBJECT *obj, LUID_ATTR *luid_attr) +NTSTATUS gums_set_priv_luid_attr(GUMS_PRIVILEGE *priv, LUID_ATTR *luid_attr) { - if (!luid_attr || !obj) + if (!luid_attr || !priv) return NT_STATUS_INVALID_PARAMETER; - if (obj->type != GUMS_OBJ_PRIVILEGE) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->data.priv->privilege = (LUID_ATTR *)talloc_memdup(obj->mem_ctx, luid_attr, sizeof(LUID_ATTR)); - if (!(obj->data.priv->privilege)) return NT_STATUS_NO_MEMORY; + priv->privilege = (LUID_ATTR *)talloc_memdup(priv->mem_ctx, luid_attr, sizeof(LUID_ATTR)); + if (!(priv->privilege)) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } -NTSTATUS gums_set_priv_members(GUMS_OBJECT *obj, uint32 count, DOM_SID *members) +NTSTATUS gums_set_priv_members(GUMS_PRIVILEGE *priv, uint32 count, DOM_SID *members) { uint32 n; - if (!obj || !members || !members) + if (!priv || !members || !members) return NT_STATUS_INVALID_PARAMETER; - if (obj->type != GUMS_OBJ_PRIVILEGE) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - - obj->data.priv->count = count; - obj->data.priv->members = (DOM_SID *)talloc(obj->mem_ctx, count * sizeof(DOM_SID)); - if (!(obj->data.priv->members)) + priv->count = count; + priv->members = (DOM_SID *)talloc(priv->mem_ctx, count * sizeof(DOM_SID)); + if (!(priv->members)) return NT_STATUS_NO_MEMORY; n = 0; do { - sid_copy(&(obj->data.priv->members[n]), &(members[n])); + sid_copy(&(priv->members[n]), &(members[n])); n++; } while (n < count); -- cgit From beb8292fd60524c54661e48b5f4a51b97c935166 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 29 Jan 2004 10:09:12 +0000 Subject: reactivate pdb_gums as static module (This used to be commit 9836def8a90bc3b375f070e91dbfabd8177f24b3) --- source3/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index bdcaa4cacb..7e27839c63 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -319,7 +319,7 @@ DYNEXP= dnl Add modules that have to be built by default here dnl These have to be built static: -default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_epmapper auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin gums_tdbsam2" +default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_epmapper auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin pdb_gums gums_tdbsam2" dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap charset_CP850 charset_CP437" -- cgit From d8522e938201e0f85acbb216197b486d6f59b0cb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 29 Jan 2004 14:05:38 +0000 Subject: BUG 570: don't overwrite LDFLAGS; patch from MORIYAMA Masayuki (This used to be commit e94590fd5a85117d170c14640cf79b603a5b1d22) --- source3/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index 7e27839c63..94f623f6e3 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1642,7 +1642,7 @@ dnl Try to find iconv(3) jm_ICONV($i) if test "$ICONV_FOUND" = yes; then - LDFLAGS=$save_LDFLAG + LDFLAGS=$save_LDFLAGS LIB_ADD_DIR(LDFLAGS, "$i/lib") CFLAGS_ADD_DIR(CPPFLAGS, "$i/include") LIBS="$save_LIBS" -- cgit From 5ef984bd52ad1d467bec9f2b06ebecbba4d2f3ca Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 29 Jan 2004 18:07:57 +0000 Subject: removing more unused parameters (This used to be commit c81c0ffaabaa805211d9c6e1ab5aa66a02365e26) --- source3/param/loadparm.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 7afad4069b..4b6c51045e 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -163,7 +163,6 @@ typedef struct char *szUtmpDir; char *szWtmpDir; BOOL bUtmp; - char *szSourceEnv; char *szIdmapUID; char *szIdmapGID; BOOL bEnableRidAlgorithm; @@ -209,7 +208,6 @@ typedef struct int max_ttl; int max_wins_ttl; int min_wins_ttl; - int ReadSize; int lm_announce; int lm_interval; int announce_as; /* This is initialised in init_globals */ @@ -256,7 +254,6 @@ typedef struct BOOL bLargeReadwrite; BOOL bReadRaw; BOOL bWriteRaw; - BOOL bReadPrediction; BOOL bReadbmpx; BOOL bSyslogOnly; BOOL bBrowseList; @@ -934,7 +931,6 @@ static struct parm_struct parm_table[] = { {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED}, {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED}, {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, - {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, FLAG_ADVANCED}, {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED}, {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, @@ -1132,7 +1128,6 @@ static struct parm_struct parm_table[] = { {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE }, {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, - {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, FLAG_ADVANCED}, {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, @@ -1396,7 +1391,6 @@ static void init_globals(void) Globals.serverSchannel = Auto; Globals.bReadRaw = True; Globals.bWriteRaw = True; - Globals.bReadPrediction = False; Globals.bReadbmpx = False; Globals.bNullPasswords = False; Globals.bObeyPamRestrictions = False; @@ -1413,7 +1407,6 @@ static void init_globals(void) Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */ Globals.change_notify_timeout = 60; /* 1 minute default. */ Globals.bKernelChangeNotify = True; /* On if we have it. */ - Globals.ReadSize = 16 * 1024; Globals.lm_announce = 2; /* = Auto: send only if LM clients found */ Globals.lm_interval = 60; Globals.announce_as = ANNOUNCE_AS_NT_SERVER; @@ -1641,7 +1634,6 @@ FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir) FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir) FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp) FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir) -FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv) FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService) FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand) FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree) @@ -1727,7 +1719,6 @@ FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy) FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster) FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons) FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters) -FN_GLOBAL_BOOL(lp_readprediction, &Globals.bReadPrediction) FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx) FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw) FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite) @@ -1781,7 +1772,6 @@ FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit) FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux) FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel) FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel) -FN_GLOBAL_INTEGER(lp_readsize, &Globals.ReadSize) FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime) FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol) FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol) -- cgit From 90c2090116606cd1ac817a238b60a8321d67fa5d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 29 Jan 2004 20:16:34 +0000 Subject: merge from 3.0 (This used to be commit 77335cc5bce46ab3498f9401099f110b0e5506c1) --- source3/passdb/pdb_get_set.c | 12 ++++++++++-- source3/passdb/pdb_interface.c | 41 +++++++++++++++++++++++++++++++++++++++++ source3/script/mksmbpasswd.sh | 2 +- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 11df0ad56d..869165f1dc 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -925,7 +925,11 @@ BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[NT_HASH_LEN], enum data_blob_clear_free(&sampass->private.nt_pw); - sampass->private.nt_pw = data_blob(pwd, NT_HASH_LEN); + if (pwd) { + sampass->private.nt_pw = data_blob(pwd, NT_HASH_LEN); + } else { + sampass->private.nt_pw = data_blob(NULL, 0); + } return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag); } @@ -941,7 +945,11 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN], data_blob_clear_free(&sampass->private.lm_pw); - sampass->private.lm_pw = data_blob(pwd, LM_HASH_LEN); + if (pwd) { + sampass->private.lm_pw = data_blob(pwd, LM_HASH_LEN); + } else { + sampass->private.lm_pw = data_blob(NULL, 0); + } return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag); } diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 3592d5f0fd..1087624aca 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -36,6 +36,44 @@ static void lazy_initialize_passdb(void) static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name); +/******************************************************************* + Clean up uninitialised passwords. The only way to tell + that these values are not 'real' is that they do not + have a valid last set time. Instead, the value is fixed at 0. + Therefore we use that as the key for 'is this a valid password'. + However, it is perfectly valid to have a 'default' last change + time, such LDAP with a missing attribute would produce. +********************************************************************/ + +static void pdb_force_pw_initialization(SAM_ACCOUNT *pass) +{ + const char *lm_pwd, *nt_pwd; + + /* only reset a password if the last set time has been + explicitly been set to zero. A default last set time + is ignored */ + + if ( (pdb_get_init_flags(pass, PDB_PASSLASTSET) != PDB_DEFAULT) + && (pdb_get_pass_last_set_time(pass) == 0) ) + { + + if (pdb_get_init_flags(pass, PDB_LMPASSWD) != PDB_DEFAULT) + { + lm_pwd = pdb_get_lanman_passwd(pass); + if (lm_pwd) + pdb_set_lanman_passwd(pass, NULL, PDB_SET); + } + if (pdb_get_init_flags(pass, PDB_NTPASSWD) != PDB_DEFAULT) + { + nt_pwd = pdb_get_nt_passwd(pass); + if (nt_pwd) + pdb_set_nt_passwd(pass, NULL, PDB_SET); + } + } + + return; +} + NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init) { struct pdb_init_function_entry *entry = backends; @@ -141,6 +179,7 @@ static NTSTATUS context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *us context->pwent_methods->setsampwent(context->pwent_methods, False); } user->methods = context->pwent_methods; + pdb_force_pw_initialization(user); return ret; } @@ -156,6 +195,7 @@ static NTSTATUS context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sa curmethods = context->pdb_methods; while (curmethods){ if (NT_STATUS_IS_OK(ret = curmethods->getsampwnam(curmethods, sam_acct, username))) { + pdb_force_pw_initialization(sam_acct); sam_acct->methods = curmethods; return ret; } @@ -179,6 +219,7 @@ static NTSTATUS context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sa while (curmethods){ if (NT_STATUS_IS_OK(ret = curmethods->getsampwsid(curmethods, sam_acct, sid))) { + pdb_force_pw_initialization(sam_acct); sam_acct->methods = curmethods; return ret; } diff --git a/source3/script/mksmbpasswd.sh b/source3/script/mksmbpasswd.sh index 854e1bd1b5..119a55611e 100755 --- a/source3/script/mksmbpasswd.sh +++ b/source3/script/mksmbpasswd.sh @@ -2,5 +2,5 @@ awk 'BEGIN {FS=":" printf("#\n# SMB password file.\n#\n") } -{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U ]:LCT-00000000:%s\n", $1, $3, $5) } +{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[UD ]:LCT-00000000:%s\n", $1, $3, $5) } ' -- cgit From 69605c14abfa9a98e5b162d582e2f3d03c5cc4df Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 29 Jan 2004 22:17:27 +0000 Subject: more initialization fixes (This used to be commit 63206b1204bd532bf99912cd4312baf7d69db1f6) --- source3/passdb/pdb_interface.c | 22 ++++++++++++++++++++++ source3/utils/pdbedit.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 1087624aca..2640e5bfe4 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -813,22 +813,44 @@ BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid) BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) { struct pdb_context *pdb_context = pdb_get_static_context(False); + const char *lm_pw, *nt_pw; + uint16 acb_flags; if (!pdb_context) { return False; } + /* disable acccounts with no passwords */ + lm_pw = pdb_get_lanman_passwd( sam_acct ); + nt_pw = pdb_get_lanman_passwd( sam_acct ); + if ( !lm_pw || !nt_pw ) { + acb_flags = pdb_get_acct_ctrl( sam_acct ) | ACB_DISABLED; + pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_SET ); + pdb_set_init_flags(sam_acct, PDB_ACCTCTRL, PDB_SET); + } + return NT_STATUS_IS_OK(pdb_context->pdb_add_sam_account(pdb_context, sam_acct)); } BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct) { struct pdb_context *pdb_context = pdb_get_static_context(False); + const char *lm_pw, *nt_pw; + uint16 acb_flags; if (!pdb_context) { return False; } + /* disable acccounts with no passwords */ + lm_pw = pdb_get_lanman_passwd( sam_acct ); + nt_pw = pdb_get_lanman_passwd( sam_acct ); + if ( !lm_pw || !nt_pw ) { + acb_flags = pdb_get_acct_ctrl( sam_acct ) | ACB_DISABLED; + pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_SET ); + pdb_set_init_flags(sam_acct, PDB_ACCTCTRL, PDB_SET); + } + return NT_STATUS_IS_OK(pdb_context->pdb_update_sam_account(pdb_context, sam_acct)); } diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index d72634d78b..f402567b74 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -47,6 +47,7 @@ #define BIT_RESERV_7 0x00800000 #define BIT_IMPORT 0x01000000 #define BIT_EXPORT 0x02000000 +#define BIT_FIX_INIT 0x04000000 #define MASK_ALWAYS_GOOD 0x0000001F #define MASK_USER_GOOD 0x00401F00 @@ -233,6 +234,39 @@ static int print_users_list (struct pdb_context *in, BOOL verbosity, BOOL smbpwd return 0; } +/********************************************************* + Fix a list of Users for uninitialised passwords +**********************************************************/ +static int fix_users_list (struct pdb_context *in) +{ + SAM_ACCOUNT *sam_pwent=NULL; + BOOL check, ret; + + check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False)); + if (!check) { + return 1; + } + + check = True; + if (!(NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent)))) return 1; + + while (check && (ret = NT_STATUS_IS_OK(in->pdb_getsampwent (in, sam_pwent)))) { + if (!pdb_update_sam_account(sam_pwent)) { + DEBUG(0, ("Update of user %s failed!\n", pdb_get_username(sam_pwent))); + } + pdb_free_sam(&sam_pwent); + check = NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent)); + if (!check) { + DEBUG(0, ("Failed to initialise new SAM_ACCOUNT structure (out of memory?)\n")); + } + + } + if (check) pdb_free_sam(&sam_pwent); + + in->pdb_endsampwent(in); + return 0; +} + /********************************************************* Set User Info **********************************************************/ @@ -550,6 +584,7 @@ int main (int argc, char **argv) static char *backend_in = NULL; static char *backend_out = NULL; static BOOL transfer_groups = False; + static BOOL force_initialised_password = False; static char *logon_script = NULL; static char *profile_path = NULL; static char *account_control = NULL; @@ -587,6 +622,7 @@ int main (int argc, char **argv) {"account-policy", 'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL}, {"value", 'C', POPT_ARG_LONG, &account_policy_value, 'C',"set the account policy to this value", NULL}, {"account-control", 'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL}, + {"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL}, POPT_COMMON_SAMBA POPT_TABLEEND }; @@ -631,6 +667,7 @@ int main (int argc, char **argv) (machine ? BIT_MACHINE : 0) + (user_name ? BIT_USER : 0) + (list_users ? BIT_LIST : 0) + + (force_initialised_password ? BIT_FIX_INIT : 0) + (modify_user ? BIT_MODIFY : 0) + (add_user ? BIT_CREATE : 0) + (delete_user ? BIT_DELETE : 0) + @@ -655,6 +692,10 @@ int main (int argc, char **argv) /* the lowest bit options are always accepted */ checkparms = setparms & ~MASK_ALWAYS_GOOD; + if (checkparms & BIT_FIX_INIT) { + return fix_users_list(bdef); + } + /* account policy operations */ if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) { uint32 value; -- cgit From 799d5494c744acadbe47b02de6a67ffa6dcf892d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Jan 2004 15:00:57 +0000 Subject: disable any account that doesn't have a password and doesn't had the ACB_PWNOTREQ bit set (This used to be commit 6c4de7198b94a8cea176e1c9d86deb65705f9058) --- source3/passdb/pdb_interface.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 2640e5bfe4..8c93aaae1e 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -819,12 +819,15 @@ BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) if (!pdb_context) { return False; } + + /* disable acccounts with no passwords (that has not + been allowed by the ACB_PWNOTREQ bit */ - /* disable acccounts with no passwords */ lm_pw = pdb_get_lanman_passwd( sam_acct ); nt_pw = pdb_get_lanman_passwd( sam_acct ); - if ( !lm_pw || !nt_pw ) { - acb_flags = pdb_get_acct_ctrl( sam_acct ) | ACB_DISABLED; + acb_flags = pdb_get_acct_ctrl( sam_acct ); + if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) { + acb_flags |= ACB_DISABLED; pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_SET ); pdb_set_init_flags(sam_acct, PDB_ACCTCTRL, PDB_SET); } @@ -842,11 +845,14 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct) return False; } - /* disable acccounts with no passwords */ + /* disable acccounts with no passwords (that has not + been allowed by the ACB_PWNOTREQ bit */ + lm_pw = pdb_get_lanman_passwd( sam_acct ); nt_pw = pdb_get_lanman_passwd( sam_acct ); - if ( !lm_pw || !nt_pw ) { - acb_flags = pdb_get_acct_ctrl( sam_acct ) | ACB_DISABLED; + acb_flags = pdb_get_acct_ctrl( sam_acct ); + if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) { + acb_flags |= ACB_DISABLED; pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_SET ); pdb_set_init_flags(sam_acct, PDB_ACCTCTRL, PDB_SET); } -- cgit From 14fb4b8e06368a2492f277492311fefdfffadaee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Jan 2004 18:38:46 +0000 Subject: Fix up name canonicalization (needed for krb5 keytab support later). Remove source_env handler (no longer used in any codepath). Jeremy. (This used to be commit be60768e64ae2061f220faa3943dcb0588393dbc) --- source3/lib/util.c | 74 ++++++++++++++----------------------- source3/libsmb/ntlmssp.c | 5 +-- source3/nmbd/nmbd_processlogon.c | 2 +- source3/param/loadparm.c | 4 +- source3/printing/nt_printing.c | 2 +- source3/rpc_server/srv_lsa_ds_nt.c | 4 +- source3/rpc_server/srv_lsa_nt.c | 2 +- source3/rpc_server/srv_spoolss_nt.c | 2 +- 8 files changed, 39 insertions(+), 56 deletions(-) diff --git a/source3/lib/util.c b/source3/lib/util.c index 4f4e0eb5d7..3da4e536e0 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -932,26 +932,33 @@ BOOL get_myname(char *my_name) } /**************************************************************************** - Get my own name, including domain. + Get my own canonical name, including domain. ****************************************************************************/ -BOOL get_myfullname(char *my_name) +BOOL get_mydnsfullname(fstring my_dnsname) { - pstring hostname; + static fstring dnshostname; + struct hostent *hp; - *hostname = 0; + if (!*dnshostname) { + /* get my host name */ + if (gethostname(dnshostname, sizeof(dnshostname)) == -1) { + *dnshostname = '\0'; + DEBUG(0,("gethostname failed\n")); + return False; + } - /* get my host name */ - if (gethostname(hostname, sizeof(hostname)) == -1) { - DEBUG(0,("gethostname failed\n")); - return False; - } + /* Ensure null termination. */ + dnshostname[sizeof(dnshostname)-1] = '\0'; - /* Ensure null termination. */ - hostname[sizeof(hostname)-1] = '\0'; - - if (my_name) - fstrcpy(my_name, hostname); + /* Ensure we get the cannonical name. */ + if (!(hp = sys_gethostbyname(dnshostname))) { + *dnshostname = '\0'; + return False; + } + fstrcpy(dnshostname, hp->h_name); + } + fstrcpy(my_dnsname, dnshostname); return True; } @@ -959,44 +966,19 @@ BOOL get_myfullname(char *my_name) Get my own domain name. ****************************************************************************/ -BOOL get_mydomname(fstring my_domname) +BOOL get_mydnsdomname(fstring my_domname) { - pstring hostname; + fstring domname; char *p; - struct hostent *hp; - *hostname = 0; - /* get my host name */ - if (gethostname(hostname, sizeof(hostname)) == -1) { - DEBUG(0,("gethostname failed\n")); - return False; - } - - /* Ensure null termination. */ - hostname[sizeof(hostname)-1] = '\0'; - - - p = strchr_m(hostname, '.'); - - if (p) { - p++; - - if (my_domname) - fstrcpy(my_domname, p); - } - - if (!(hp = sys_gethostbyname(hostname))) { + *my_domname = '\0'; + if (!get_mydnsfullname(domname)) { return False; - } - - p = strchr_m(hp->h_name, '.'); - + } + p = strchr_m(domname, '.'); if (p) { p++; - - if (my_domname) - fstrcpy(my_domname, p); - return True; + fstrcpy(my_domname, p); } return False; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index a80b4b66b0..60523ddf9d 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -433,12 +433,11 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; - get_mydomname(dnsdomname); + get_mydnsdomname(dnsdomname); strlower_m(dnsdomname); dnsname[0] = '\0'; - get_myfullname(dnsname); - strlower_m(dnsname); + get_mydnsfullname(dnsname); /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index 6b806f2a05..13aefabd26 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -322,7 +322,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", char *q_orig = q; int str_offset; - get_mydomname(domain); + get_mydnsdomname(domain); get_myname(hostname); if (SVAL(uniuser, 0) == 0) { diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 4b6c51045e..1fa3efabf8 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -556,7 +556,6 @@ static int default_server_announce; /* prototypes for the special type handlers */ static BOOL handle_include(const char *pszParmValue, char **ptr); static BOOL handle_copy(const char *pszParmValue, char **ptr); -static BOOL handle_source_env(const char *pszParmValue, char **ptr); static BOOL handle_netbios_name(const char *pszParmValue, char **ptr); static BOOL handle_idmap_uid(const char *pszParmValue, char **ptr); static BOOL handle_idmap_gid(const char *pszParmValue, char **ptr); @@ -2803,6 +2802,8 @@ static BOOL source_env(char **lines) return (True); } +#if 0 +/* Doesn't seem to be used anymore. JRA */ /*************************************************************************** Handle the source environment operation. ***************************************************************************/ @@ -2842,6 +2843,7 @@ static BOOL handle_source_env(const char *pszParmValue, char **ptr) return (result); } +#endif /*************************************************************************** Handle the include operation. diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 34274d1831..8aa02b57b6 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2537,7 +2537,7 @@ static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2) map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename); map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname()); - get_myfullname(longname); + get_mydnsfullname(longname); map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname); asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename); diff --git a/source3/rpc_server/srv_lsa_ds_nt.c b/source3/rpc_server/srv_lsa_ds_nt.c index 97e9dc361d..f6e8eed9a9 100644 --- a/source3/rpc_server/srv_lsa_ds_nt.c +++ b/source3/rpc_server/srv_lsa_ds_nt.c @@ -58,7 +58,7 @@ static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE; if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) ) basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT; - get_mydomname(dnsdomain); + get_mydnsdomname(dnsdomain); strlower_m(dnsdomain); break; case ROLE_DOMAIN_PDC: @@ -66,7 +66,7 @@ static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE; if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) ) basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT; - get_mydomname(dnsdomain); + get_mydnsdomname(dnsdomain); strlower_m(dnsdomain); break; } diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 01a31dcfe5..4a3f6ddbf1 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -1250,7 +1250,7 @@ NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_I /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; - get_mydomname(dnsdomname); + get_mydnsdomname(dnsdomname); strlower_m(dnsdomname); dns_name = dnsdomname; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index ad8f5af432..b5f5bffbb4 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -2431,7 +2431,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint if (!StrCaseCmp(value, "DNSMachineName")) { pstring hostname; - if (!get_myfullname(hostname)) + if (!get_mydnsfullname(hostname)) return WERR_BADFILE; *type = 0x1; *needed = 2*(strlen(hostname)+1); -- cgit From c21764b9214dce72f3c07a578d9c6a5c120bd95f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 30 Jan 2004 23:53:47 +0000 Subject: (merge from 3.0) If we are setting the NT or LM password to NULL, remove the attribute rather than writing XXXXX Andrew Bartlett (This used to be commit 2ae9672f811c91c95ee2ddfd4b0dcc6b0f4fa192) --- source3/passdb/pdb_ldap.c | 48 ++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index ff2b5cf762..dcb2040530 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -910,27 +910,41 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) { - pdb_sethexpwd(temp, pdb_get_lanman_passwd(sampass), - pdb_get_acct_ctrl(sampass)); - - if (need_update(sampass, PDB_LMPASSWD)) - smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, - get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), - temp); - - pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), - pdb_get_acct_ctrl(sampass)); - - if (need_update(sampass, PDB_NTPASSWD)) - smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, - get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), - temp); + if (need_update(sampass, PDB_LMPASSWD)) { + uchar *lm_pw = pdb_get_lanman_passwd(sampass); + if (lm_pw) { + pdb_sethexpwd(temp, lm_pw, + pdb_get_acct_ctrl(sampass)); + smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, + get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), + temp); + } else { + smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, + get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), + NULL); + } + } + if (need_update(sampass, PDB_NTPASSWD)) { + uchar *nt_pw = pdb_get_nt_passwd(sampass); + if (nt_pw) { + pdb_sethexpwd(temp, nt_pw, + pdb_get_acct_ctrl(sampass)); + smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, + get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), + temp); + } else { + smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, + get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), + NULL); + } + } - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); - if (need_update(sampass, PDB_PASSLASTSET)) + if (need_update(sampass, PDB_PASSLASTSET)) { + slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp); + } } /* FIXME: Hours stuff goes in LDAP */ -- cgit From 87d74fed8c6438cbf7dc690aed2f8f866fab95e3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 31 Jan 2004 14:45:21 +0000 Subject: cleanup patch for bug 977 so we don't display incorrect debug messages (This used to be commit d59dc1bc1cf47eee2158e5c9d56d0ed750948fa0) --- source3/smbd/password.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 36e3fb4738..10c6aadb1f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -250,17 +250,21 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, return -1; } - /* Register a home dir service for this user */ - if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { - DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n", - vuser->user.unix_name, vuser->unix_homedir)); + /* Register a home dir service for this user iff + (a) This is not a guest connection, + (b) we have a home directory defined, and + (c) there s not an existing static share by that name */ + + if ( (!vuser->guest) + && vuser->unix_homedir + && *(vuser->unix_homedir) + && (lp_servicenumber(vuser->user.unix_name) == -1) ) + { + DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n", + vuser->user.unix_name, vuser->unix_homedir)); - /* only add the home directory if there doesn't exist a static share by that name */ - if ( lp_servicenumber(vuser->user.unix_name) == -1 ) { vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir); - } - } else { vuser->homes_snum = -1; } -- cgit From e827764d0a6a39f587a7d3143e22b3887112b41e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 31 Jan 2004 18:27:35 +0000 Subject: * BUG 101: patch from j.lu@tiesse.com to set the SV_TYPE_PRINTQ_SERVER; * don't set the unix_ERR_XX code in mkdir_internal, let the error mapping handle it. (This used to be commit 758bbfb5f133c3c85e3092ad88294ae4abbbbc6f) --- source3/param/loadparm.c | 110 +++-------------------------------------------- source3/smbd/reply.c | 15 ++----- 2 files changed, 10 insertions(+), 115 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 1fa3efabf8..e0c6f821a1 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -2399,8 +2399,6 @@ BOOL lp_add_printer(const char *pszPrintername, int iDefaultService) DEBUG(3, ("adding printer service %s\n", pszPrintername)); - update_server_announce_as_printserver(); - return (True); } @@ -2752,99 +2750,6 @@ static BOOL handle_netbios_aliases(const char *pszParmValue, char **ptr) return set_netbios_aliases((const char **)Globals.szNetbiosAliases); } -/*************************************************************************** - Do the work of sourcing in environment variable/value pairs. -***************************************************************************/ - -static BOOL source_env(char **lines) -{ - char *varval; - size_t len; - int i; - char *p; - - for (i = 0; lines[i]; i++) { - char *line = lines[i]; - - if ((len = strlen(line)) == 0) - continue; - - if (line[len - 1] == '\n') - line[--len] = '\0'; - - if ((varval = malloc(len + 1)) == NULL) { - DEBUG(0, ("source_env: Not enough memory!\n")); - return (False); - } - - DEBUG(4, ("source_env: Adding to environment: %s\n", line)); - strncpy(varval, line, len); - varval[len] = '\0'; - - p = strchr_m(line, (int)'='); - if (p == NULL) { - DEBUG(4, ("source_env: missing '=': %s\n", line)); - continue; - } - - if (putenv(varval)) { - DEBUG(0, ("source_env: Failed to put environment variable %s\n", - varval)); - continue; - } - - *p = '\0'; - p++; - DEBUG(4, ("source_env: getting var %s = %s\n", line, getenv(line))); - } - - DEBUG(4, ("source_env: returning successfully\n")); - return (True); -} - -#if 0 -/* Doesn't seem to be used anymore. JRA */ -/*************************************************************************** - Handle the source environment operation. -***************************************************************************/ - -static BOOL handle_source_env(const char *pszParmValue, char **ptr) -{ - pstring fname; - char *p = fname; - BOOL result; - char **lines; - - pstrcpy(fname, pszParmValue); - - standard_sub_basic(current_user_info.smb_name, fname,sizeof(fname)); - - string_set(ptr, pszParmValue); - - DEBUG(4, ("handle_source_env: checking env type\n")); - - /* - * Filename starting with '|' means popen and read from stdin. - */ - - if (*p == '|') - lines = file_lines_pload(p + 1, NULL); - else - lines = file_lines_load(fname, NULL); - - if (!lines) { - DEBUG(0, ("handle_source_env: Failed to open file %s, Error was %s\n", - fname, strerror(errno))); - return (False); - } - - result = source_env(lines); - file_lines_free(lines); - - return (result); -} -#endif - /*************************************************************************** Handle the include operation. ***************************************************************************/ @@ -3724,15 +3629,6 @@ void lp_add_one_printer(char *name, char *comment) } } -/*************************************************************************** - Announce ourselves as a print server. -***************************************************************************/ - -void update_server_announce_as_printserver(void) -{ - default_server_announce |= SV_TYPE_PRINTQ_SERVER; -} - /*************************************************************************** Have we loaded a services file yet? ***************************************************************************/ @@ -4102,6 +3998,12 @@ static void set_default_server_announce_type(void) default_server_announce |= SV_TYPE_SERVER; default_server_announce |= SV_TYPE_SERVER_UNIX; + /* note that the flag should be set only if we have a + printer service but nmbd doesn't actually load the + services so we can't tell --jerry */ + + default_server_announce |= SV_TYPE_PRINTQ_SERVER; + switch (lp_announce_as()) { case ANNOUNCE_AS_NT_SERVER: default_server_announce |= SV_TYPE_SERVER_NT; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 3752507493..c4ff77bd86 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3013,19 +3013,12 @@ NTSTATUS mkdir_internal(connection_struct *conn, pstring directory) ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory)); if (ret == -1) { - NTSTATUS nterr = NT_STATUS_OK; if(errno == ENOENT) { - unix_ERR_class = ERRDOS; - if (bad_path) { - unix_ERR_code = ERRbadpath; - nterr = NT_STATUS_OBJECT_PATH_NOT_FOUND; - } else { - unix_ERR_code = ERRbadfile; - nterr = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } + if (bad_path) + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + else + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - if (!NT_STATUS_IS_OK(nterr)) - return nterr; return map_nt_error_from_unix(errno); } -- cgit From d16540d3c4794010bb6ca8f4c29d68b527195d83 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 1 Feb 2004 11:10:55 +0000 Subject: Merge from 3.0: >Don't log an error if a tdb_brlock() returns EAGAIN - it's supposed to >do that. (This used to be commit d8182b8bf54dc00378caa82e8c325891a08b17ca) --- source3/tdb/tdb.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index ff70750385..7ad39175ac 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -242,10 +242,14 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, tdb->fd, offset, rw_type, lck_type)); return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1); } - /* Otherwise - generic lock error. */ - /* errno set by fcntl */ - TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n", - tdb->fd, offset, rw_type, lck_type, strerror(errno))); + /* Otherwise - generic lock error. errno set by fcntl. + * EAGAIN is an expected return from non-blocking + * locks. */ + if (errno != EAGAIN) { + TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n", + tdb->fd, offset, rw_type, lck_type, + strerror(errno))); + } return TDB_ERRCODE(TDB_ERR_LOCK, -1); } return 0; -- cgit From 152e2282164069d63dde7b15f96d637db5a25245 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 1 Feb 2004 22:19:01 +0000 Subject: Merge from 3.0: >Include sys/acl.h in check for broken nisplus include files. Bug #1025. (This used to be commit cbf9c3d3953e25999312492dc08f61db875a04e7) --- source3/configure.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index 94f623f6e3..af6836f060 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2211,7 +2211,9 @@ fi esac AC_CACHE_CHECK([for broken nisplus include files],samba_cv_BROKEN_NISPLUS_INCLUDE_FILES,[ -AC_TRY_COMPILE([#include +AC_TRY_COMPILE([ +#include +#include #if defined(HAVE_RPCSVC_NIS_H) #include #endif], -- cgit From a870ff546ce9128e3bf8bb3ddc88f5eeb98d2eda Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 2 Feb 2004 01:46:30 +0000 Subject: janitor duty (merges from 3.0) and cleanup compiler warning on SuSE 9 in the end mapper code (This used to be commit 902d4a647a88d1def09d5b1eacb06ab1561f3dec) --- examples/misc/modify_samba_config.pl | 2 +- packaging/Fedora/makerpms.sh.tmpl | 3 +- packaging/Fedora/samba.pamd | 6 +- packaging/Fedora/samba.spec.tmpl | 662 +++-------------------------------- packaging/Fedora/smb.conf | 286 +++++++++++++++ packaging/Fedora/smb.init | 8 +- packaging/Fedora/smbusers | 3 + packaging/Fedora/winbind.init | 6 +- packaging/RedHat/samba.spec.tmpl | 201 +++++------ packaging/SuSE/samba3.spec | 1 + source3/groupdb/mapping.c | 74 ++-- source3/nsswitch/winbind_nss_linux.c | 138 ++++++++ source3/nsswitch/winbindd_group.c | 4 +- source3/rpc_parse/parse_epmapper.c | 96 ++--- swat/lang/ja/help/welcome.html | 155 ++++---- 15 files changed, 749 insertions(+), 896 deletions(-) create mode 100644 packaging/Fedora/smb.conf create mode 100644 packaging/Fedora/smbusers diff --git a/examples/misc/modify_samba_config.pl b/examples/misc/modify_samba_config.pl index eb997f9b0c..ad958625d6 100755 --- a/examples/misc/modify_samba_config.pl +++ b/examples/misc/modify_samba_config.pl @@ -66,7 +66,7 @@ while () { ## check for a param = value if ($_ =~ /=/) { - ($param, $value) = split (/=/, $_); + ($param, $value) = split (/=/, $_,2); $param =~ s/./\l$&/g; $param =~ s/\s+//g; $value =~ s/^\s+//; diff --git a/packaging/Fedora/makerpms.sh.tmpl b/packaging/Fedora/makerpms.sh.tmpl index 46ef4b6353..361d841876 100644 --- a/packaging/Fedora/makerpms.sh.tmpl +++ b/packaging/Fedora/makerpms.sh.tmpl @@ -46,7 +46,8 @@ esac ## for file in samba.pamd samba.sysconfig samba.spec \ smb.init swat.desktop filter-requires-samba.sh \ - samba.log samba.xinetd smbprint winbind.init + samba.log samba.xinetd smbprint winbind.init \ + smb.conf smbusers do cp -p $file ${SRCDIR} diff --git a/packaging/Fedora/samba.pamd b/packaging/Fedora/samba.pamd index d8a27ff08f..f88aae628c 100644 --- a/packaging/Fedora/samba.pamd +++ b/packaging/Fedora/samba.pamd @@ -1,2 +1,4 @@ -auth required /lib/security/pam_stack.so service=system-auth -account required /lib/security/pam_stack.so service=system-auth +auth required /lib/security/pam_stack.so service=system-auth +session required /lib/security/pam_stack.so service=system-auth +account required /lib/security/pam_stack.so service=system-auth +password required /lib/security/pam_stack.so service=system-auth diff --git a/packaging/Fedora/samba.spec.tmpl b/packaging/Fedora/samba.spec.tmpl index 51e68dfea2..ae6f95c900 100644 --- a/packaging/Fedora/samba.spec.tmpl +++ b/packaging/Fedora/samba.spec.tmpl @@ -12,14 +12,15 @@ URL: http://www.samba.org/ Source: ftp://www.samba.org/pub/samba/%{name}-%{version}.tar.bz2 # Red Hat specific replacement-files -Source1: samba.log -Source2: samba.xinetd -Source3: swat.desktop -Source4: samba.sysconfig -Source5: smb.init -Source6: samba.pamd -Source7: smbprint -Source8: winbind.init +Source1: samba.log +Source2: samba.xinetd +Source4: samba.sysconfig +Source5: smb.init +Source6: winbind.init +Source7: samba.pamd +Source8: smbprint +Source9: smbusers +Source10: smb.conf # Don't depend on Net::LDAP Source999: filter-requires-samba.sh @@ -144,20 +145,26 @@ make DESTDIR=$RPM_BUILD_ROOT \ cd .. # Install other stuff -install -m644 packaging/RedHat/smb.conf $RPM_BUILD_ROOT%{_sysconfdir}/samba/smb.conf +install -m644 %{SOURCE10} $RPM_BUILD_ROOT%{_sysconfdir}/samba/smb.conf +install -m644 %{SOURCE8} $RPM_BUILD_ROOT/etc/samba/smbusers +install -m755 %{SOURCE8} $RPM_BUILD_ROOT%{_bindir} +install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/pam.d/samba +install -m644 %{SOURCE1} $RPM_BUILD_ROOT/etc/logrotate.d/samba install -m755 source/script/mksmbpasswd.sh $RPM_BUILD_ROOT%{_bindir} -install -m644 packaging/RedHat/smbusers $RPM_BUILD_ROOT/etc/samba/smbusers -install -m755 packaging/RedHat/smbprint $RPM_BUILD_ROOT%{_bindir} -install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT%{initdir}/smb -install -m755 packaging/RedHat/winbind.init $RPM_BUILD_ROOT%{initdir}/winbind + +install -m755 %{SOURCE5} $RPM_BUILD_ROOT%{initdir}/smb +install -m755 %{SOURCE6} $RPM_BUILD_ROOT%{initdir}/winbind ln -s ../..%{initdir}/smb $RPM_BUILD_ROOT%{_sbindir}/samba -install -m644 packaging/RedHat/samba.pamd.stack $RPM_BUILD_ROOT/etc/pam.d/samba -install -m644 $RPM_SOURCE_DIR/samba.log $RPM_BUILD_ROOT/etc/logrotate.d/samba +ln -s ../..%{initdir}/winbind $RPM_BUILD_ROOT%{_sbindir}/winbind + ln -s ../usr/bin/smbmount $RPM_BUILD_ROOT/sbin/mount.smb -## mount.smbfs is installed by Samba's Makefile -## ln -s ../usr/bin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs +## Samba's Makefile is breaking this currently. Remove it and set our own +/bin/rm -f $RPM_BUILD_ROOT/sbin/mount.smbfs +ln -s ../usr/bin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs + echo 127.0.0.1 localhost > $RPM_BUILD_ROOT%{_sysconfdir}/samba/lmhosts + # pam_smbpass mkdir -p $RPM_BUILD_ROOT/%{_lib}/security mv source/bin/pam_smbpass.so $RPM_BUILD_ROOT/%{_lib}/security/pam_smbpass.so @@ -165,11 +172,11 @@ mv source/bin/pam_smbpass.so $RPM_BUILD_ROOT/%{_lib}/security/pam_smbpass.so # winbind mkdir -p $RPM_BUILD_ROOT/%{_lib}/security install -m 755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/%{_lib}/security/pam_winbind.so -mkdir -p $RPM_BUILD_ROOT%{_libdir} install -m 755 source/nsswitch/libnss_winbind.so $RPM_BUILD_ROOT/%{_lib}/libnss_winbind.so -ln -sf /%{_lib}/libnss_winbind.so $RPM_BUILD_ROOT%{_libdir}/libnss_winbind.so.2 install -m 755 source/nsswitch/libnss_wins.so $RPM_BUILD_ROOT/%{_lib}/libnss_wins.so -ln -sf /%{_lib}/libnss_wins.so $RPM_BUILD_ROOT%{_libdir}/libnss_wins.so.2 +( cd $RPM_BUILD_ROOT/%{_lib}; + ln -sf libnss_winbind.so libnss_winbind.so.2; + ln -sf libnss_wins.so libnss_wins.so.2 ) # libsmbclient @@ -192,6 +199,7 @@ install -m644 %{SOURCE4} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/samba rm -f $RPM_BUILD_ROOT/%{_mandir}/man1/editreg.1* rm -f $RPM_BUILD_ROOT%{_mandir}/man1/log2pcap.1* rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbsh.1* +rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbget.1* rm -f $RPM_BUILD_ROOT/%{_mandir}/man8/mount.cifs.8* %clean @@ -213,6 +221,13 @@ if [ "$1" -ge "1" ]; then %{initdir}/smb condrestart >/dev/null 2>&1 fi + +%post swat +# Add swat entry to /etc/services if not already there. +if [ ! "`grep ^\s**swat /etc/services`" ]; then + echo 'swat 901/tcp # Add swat service used via inetd' >> /etc/services +fi + %post common /sbin/chkconfig --add winbind /sbin/ldconfig @@ -266,7 +281,6 @@ fi %{_mandir}/man1/smbstatus.1* %{_mandir}/man5/smbpasswd.5* %{_mandir}/man7/samba.7* -%{_mandir}/man7/Samba.7* %{_mandir}/man8/nmbd.8* %{_mandir}/man8/pdbedit.8* %{_mandir}/man8/smbd.8* @@ -303,6 +317,8 @@ fi %{_bindir}/smbmnt %{_bindir}/smbumount %{_bindir}/findsmb +%{_bindir}/tdbdump +%{_mandir}/man8/tdbdump.8* %{_mandir}/man8/smbmnt.8* %{_mandir}/man8/smbmount.8* %{_mandir}/man8/smbumount.8* @@ -328,8 +344,8 @@ fi %files common %defattr(-,root,root) -/%{_lib}/libnss_wins.so.* -/%{_lib}/libnss_winbind.so.* +/%{_lib}/libnss_wins.so* +/%{_lib}/libnss_winbind.so* /%{_lib}/security/pam_winbind.so %{_libdir}/libsmbclient.a %{_libdir}/libsmbclient.so @@ -347,8 +363,6 @@ fi %{_bindir}/smbcquotas #%{_bindir}/vfstest %{_sbindir}/winbindd -%dir /var/cache/samba -%attr(750,root,root) %dir /var/cache/samba/winbindd_privileged %config(noreplace) %{_sysconfdir}/samba/smb.conf %config(noreplace) %{_sysconfdir}/samba/lmhosts %dir %{_datadir}/samba @@ -377,602 +391,8 @@ fi #%lang(ja) %{_mandir}/ja/man8/smbpasswd.8* %changelog -* Thu Sep 25 2003 Jay Fenlason 3.0.0-15 -- New 3.0.0 final release -- merge nmbd-netbiosname and testparm patches from 3E branch -- updated the -logfiles patch to work against 3.0.0 -- updated the pie patch -- update the VERSION file during build -- use make -j if avaliable -- merge the winbindd_privileged change from 3E -- merge the "rm /usr/lib" patch that allows Samba to build on 64-bit - platforms despite the broken Makefile - -* Mon Aug 18 2003 Jay Fenlason -- Merge from samba-3E-branch after samba-3.0.0rc1 was released - -* Wed Jul 23 2003 Jay Fenlason 3.0.0-3beta3 -- Merge from 3.0.0-2beta3.3E -- (Correct log file names (#100981).) -- (Fix pidfile directory in samab.log) -- (Remove obsolete samba-3.0.0beta2.tar.bz2.md5 file) -- (Move libsmbclient to the -common package (#99449)) - -* Tue Jun 22 2003 Nalin Dahyabhai 2.2.8a-4 -- rebuild - -* Wed Jun 04 2003 Elliot Lee -- rebuilt - -* Wed May 28 2003 Jay Fenlason 2.2.8a-2 -- add libsmbclient.so for gnome-vfs-extras -- Edit specfile to specify /var/run for pid files -- Move /tmp/.winbindd/socket to /var/run/winbindd/socket - -* Wed May 14 2003 Florian La Roche -- add proper ldconfig calls - -* Thu Apr 24 2003 Jay Fenlason 2.2.8a-1 -- upgrade to 2.2.8a -- remove old .md5 files -- add "pid directory = /var/run" to the smb.conf file. Fixes #88495 -- Patch from jra@dp.samba.org to fix a delete-on-close regression - -* Mon Mar 24 2003 Jay Fenlason 2.2.8-0 -- Upgrade to 2.2.8 -- removed commented out patches. -- removed old patches and .md5 files from the repository. -- remove duplicate /sbin/chkconfig --del winbind which causes - warnings when removing samba. -- Fixed minor bug in smbprint that causes it to fail when called with - more than 10 parameters: the accounting file (and spool directory - derived from it) were being set wrong due to missing {}. This closes - bug #86473. -- updated smb.conf patch, includes new defaults to close bug #84822. - -* Mon Feb 24 2003 Elliot Lee -- rebuilt - -* Thu Feb 20 2003 Jonathan Blandford 2.2.7a-5 -- remove swat.desktop file - -* Thu Feb 20 2003 Nalin Dahyabhai 2.2.7a-4 -- relink libnss_wins.so with SHLD="%{__cc} -lnsl" to force libnss_wins.so to - link with libnsl, avoiding unresolved symbol errors on functions in libnsl - -* Mon Feb 10 2003 Jay Fenlason 2.2.7a-3 -- edited spec file to put .so files in the correct directories - on 64-bit platforms that have 32-bit compatability issues - (sparc64, x86_64, etc). This fixes bugzilla #83782. -- Added samba-2.2.7a-error.patch from twaugh. This fixes - bugzilla #82454. - -* Wed Jan 22 2003 Tim Powers -- rebuilt - -* Thu Jan 9 2003 Jay Fenlason 2.2.7a-1 -- Update to 2.2.7a -- Change default printing system to CUPS -- Turn on pam_smbpass -- Turn on msdfs - -* Sat Jan 4 2003 Jeff Johnson 2.2.7-5 -- use internal dep generator. - -* Sat Dec 14 2002 Tim Powers 2.2.7-4 -- don't use rpms internal dep generator - -* Mon Dec 02 2002 Elliot Lee 2.2.7-3 -- Fix missing doc files. -- Fix multilib issues - -* Wed Nov 20 2002 Bill Nottingham 2.2.7-2 -- update to 2.2.7 -- add patch for LFS in smbclient () - -* Wed Aug 28 2002 Trond Eivind Glomsrød 2.2.5-10 -- logrotate fixes (#65007) - -* Mon Aug 26 2002 Trond Eivind Glomsrød 2.2.5-9 -- /usr/lib was used in place of %%{_libdir} in three locations (#72554) - -* Mon Aug 5 2002 Trond Eivind Glomsrød 2.2.5-8 -- Initscript fix (#70720) - -* Fri Jul 26 2002 Trond Eivind Glomsrød 2.2.5-7 -- Enable VFS support and compile the "recycling" module (#69796) -- more selective includes of the examples dir - -* Tue Jul 23 2002 Trond Eivind Glomsrød 2.2.5-6 -- Fix the lpq parser for better handling of LPRng systems (#69352) - -* Tue Jul 23 2002 Trond Eivind Glomsrød 2.2.5-5 -- desktop file fixes (#69505) - -* Wed Jun 26 2002 Trond Eivind Glomsrød 2.2.5-4 -- Enable ACLs - -* Tue Jun 25 2002 Trond Eivind Glomsrød 2.2.5-3 -- Make it not depend on Net::LDAP - those are doc files and examples - -* Fri Jun 21 2002 Tim Powers -- automated rebuild - -* Thu Jun 20 2002 Trond Eivind Glomsrød 2.2.5-1 -- 2.2.5 - -* Fri Jun 14 2002 Trond Eivind Glomsrød 2.2.4-5 -- Move the post/preun of winbind into the -common subpackage, - where the script is (#66128) - -* Tue Jun 4 2002 Trond Eivind Glomsrød 2.2.4-4 -- Fix pidfile locations so it runs properly again (2.2.4 - added a new directtive - #65007) - -* Thu May 23 2002 Tim Powers -- automated rebuild - -* Tue May 14 2002 Trond Eivind Glomsrød 2.2.4-2 -- Fix #64804 - -* Thu May 9 2002 Trond Eivind Glomsrød 2.2.4-1 -- 2.2.4 -- Removed some zero-length and CVS internal files -- Make it build - -* Wed Apr 10 2002 Trond Eivind Glomsrød 2.2.3a-6 -- Don't use /etc/samba.d in smbadduser, it should be /etc/samba - -* Thu Apr 4 2002 Trond Eivind Glomsrød 2.2.3a-5 -- Add libsmbclient.a w/headerfile for KDE (#62202) - -* Tue Mar 26 2002 Trond Eivind Glomsrød 2.2.3a-4 -- Make the logrotate script look the correct place for the pid files - -* Thu Mar 14 2002 Nalin Dahyabhai 2.2.3a-3 -- include interfaces.o in pam_smbpass.so, which needs symbols from interfaces.o - (patch posted to samba-list by Ilia Chipitsine) - -* Thu Feb 21 2002 Trond Eivind Glomsrød 2.2.3a-2 -- Rebuild - -* Thu Feb 7 2002 Trond Eivind Glomsrød 2.2.3a-1 -- 2.2.3a - -* Mon Feb 4 2002 Trond Eivind Glomsrød 2.2.3-1 -- 2.2.3 - -* Thu Nov 29 2001 Trond Eivind Glomsrød 2.2.2-8 -- New pam configuration file for samba - -* Tue Nov 27 2001 Trond Eivind Glomsrød 2.2.2-7 -- Enable PAM session controll and password sync - -* Tue Nov 13 2001 Trond Eivind Glomsrød 2.2.2-6 -- Move winbind files to samba-common. Add separate initscript for - winbind -- Fixes for winbind - protect global variables with mutex, use - more secure getenv - -* Thu Nov 8 2001 Trond Eivind Glomsrød 2.2.2-5 -- Teach smbadduser about "getent passwd" -- Fix more pid-file references -- Add (conditional) winbindd startup to the initscript, configured in - /etc/sysconfig/samba - -* Wed Nov 7 2001 Trond Eivind Glomsrød 2.2.2-4 -- Fix pid-file reference in logrotate script -- include pam and nss modules for winbind - -* Mon Nov 5 2001 Trond Eivind Glomsrød 2.2.2-3 -- Add "--with-utmp" to configure options (#55372) -- Include winbind, pam_smbpass.so, rpcclient and smbcacls -- start using /var/cache/samba, we need to keep state and there is - more than just locks involved - -* Sat Nov 03 2001 Florian La Roche 2.2.2-2 -- add "reload" to the usage string in the startup script - -* Mon Oct 15 2001 Trond Eivind Glomsrød 2.2.2-1 -- 2.2.2 - -* Tue Sep 18 2001 Trond Eivind Glomsrød 2.2.1a-5 -- Add patch from Jeremy Allison to fix IA64 alignment problems (#51497) - -* Mon Aug 13 2001 Trond Eivind Glomsrød -- Don't include smbpasswd in samba, it's in samba-common (#51598) -- Add a disabled "obey pam restrictions" statement - it's not - active, as we use encrypted passwords, but if the admin turns - encrypted passwords off the choice is available. (#31351) - -* Wed Aug 8 2001 Trond Eivind Glomsrød -- Use /var/cache/samba instead of /var/lock/samba -- Remove "domain controller" keyword from smb.conf, it's - deprecated (from #13704) -- Sync some examples with smb.conf.default -- Fix password synchronization (#16987) - -* Fri Jul 20 2001 Trond Eivind Glomsrød -- Tweaks of BuildRequires (#49581) - -* Wed Jul 11 2001 Trond Eivind Glomsrød -- 2.2.1a bugfix release - -* Tue Jul 10 2001 Trond Eivind Glomsrød -- 2.2.1, which should work better for XP - -* Sat Jun 23 2001 Trond Eivind Glomsrød -- 2.2.0a security fix -- Mark lograte and pam configuration files as noreplace - -* Fri Jun 22 2001 Trond Eivind Glomsrød -- Add the /etc/samba directory to samba-common - -* Thu Jun 21 2001 Trond Eivind Glomsrød -- Add improvements to the smb.conf as suggested in #16931 - -* Tue Jun 19 2001 Trond Eivind Glomsrød - (these changes are from the non-head version) -- Don't include /usr/sbin/samba, it's the same as the initscript -- unset TMPDIR, as samba can't write into a TMPDIR owned - by root (#41193) -- Add pidfile: lines for smbd and nmbd and a config: line - in the initscript (#15343) -- don't use make -j -- explicitly include /usr/share/samba, not just the files in it - -* Tue Jun 19 2001 Bill Nottingham -- mount.smb/mount.smbfs go in /sbin, *not* %%{_sbindir} - -* Fri Jun 8 2001 Preston Brown -- enable encypted passwords by default - -* Thu Jun 7 2001 Helge Deller -- build as 2.2.0-1 release -- skip the documentation-directories docbook, manpages and yodldocs -- don't include *.sgml documentation in package -- moved codepage-directory to /usr/share/samba/codepages -- make it compile with glibc-2.2.3-10 and kernel-headers-2.4.2-2 - -* Mon May 21 2001 Helge Deller -- updated to samba 2.2.0 -- moved codepages to %{_datadir}/samba/codepages -- use all available CPUs for building rpm packages -- use %{_xxx} defines at most places in spec-file -- "License:" replaces "Copyright:" -- dropped excludearch sparc -- de-activated japanese patches 100 and 200 for now - (they need to be fixed and tested wth 2.2.0) -- separated swat.desktop file from spec-file and added - german translations -- moved /etc/sysconfig/samba to a separate source-file -- use htmlview instead of direct call to netscape in - swat.desktop-file - -* Mon May 7 2001 Bill Nottingham -- device-remove security fix again () - -* Fri Apr 20 2001 Bill Nottingham -- fix tempfile security problems, officially () -- update to 2.0.8 - -* Sun Apr 8 2001 Bill Nottingham -- turn of SSL, kerberos - -* Thu Apr 5 2001 Bill Nottingham -- fix tempfile security problems (patch from ) - -* Thu Mar 29 2001 Bill Nottingham -- fix quota support, and quotas with the 2.4 kernel (#31362, #33915) - -* Mon Mar 26 2001 Nalin Dahyabhai -- tweak the PAM code some more to try to do a setcred() after initgroups() -- pull in all of the optflags on i386 and sparc -- don't explicitly enable Kerberos support -- it's only used for password - checking, and if PAM is enabled it's a no-op anyway - -* Mon Mar 5 2001 Tim Waugh -- exit successfully from preun script (bug #30644). - -* Fri Mar 2 2001 Nalin Dahyabhai -- rebuild in new environment - -* Wed Feb 14 2001 Bill Nottingham -- updated japanese stuff (#27683) - -* Fri Feb 9 2001 Bill Nottingham -- fix trigger (#26859) - -* Wed Feb 7 2001 Bill Nottingham -- add i18n support, japanese patch (#26253) - -* Wed Feb 7 2001 Trond Eivind Glomsrød -- i18n improvements in initscript (#26537) - -* Wed Jan 31 2001 Bill Nottingham -- put smbpasswd in samba-common (#25429) - -* Wed Jan 24 2001 Bill Nottingham -- new i18n stuff - -* Sun Jan 21 2001 Bill Nottingham -- rebuild - -* Thu Jan 18 2001 Bill Nottingham -- i18n-ize initscript -- add a sysconfig file for daemon options (#23550) -- clarify smbpasswd man page (#23370) -- build with LFS support (#22388) -- avoid extraneous pam error messages (#10666) -- add Urban Widmark's bug fixes for smbmount (#19623) -- fix setgid directory modes (#11911) -- split swat into subpackage (#19706) - -* Wed Oct 25 2000 Nalin Dahyabhai -- set a default CA certificate path in smb.conf (#19010) -- require openssl >= 0.9.5a-20 to make sure we have a ca-bundle.crt file - -* Mon Oct 16 2000 Bill Nottingham -- fix swat only_from line (#18726, others) -- fix attempt to write outside buildroot on install (#17943) - -* Mon Aug 14 2000 Bill Nottingham -- add smbspool back in (#15827) -- fix absolute symlinks (#16125) - -* Sun Aug 6 2000 Philipp Knirsch -- bugfix for smbadduser script (#15148) - -* Mon Jul 31 2000 Matt Wilson -- patch configure.ing (patch11) to disable cups test -- turn off swat by default - -* Fri Jul 28 2000 Bill Nottingham -- fix condrestart stuff - -* Fri Jul 21 2000 Bill Nottingham -- add copytruncate to logrotate file (#14360) -- fix init script (#13708) - -* Sat Jul 15 2000 Bill Nottingham -- move initscript back -- remove 'Using Samba' book from %%doc -- move stuff to /etc/samba (#13708) -- default configuration tweaks (#13704) -- some logrotate tweaks - -* Wed Jul 12 2000 Prospector -- automatic rebuild - -* Tue Jul 11 2000 Bill Nottingham -- fix logrotate script (#13698) - -* Thu Jul 6 2000 Bill Nottingham -- fix initscripts req (prereq /etc/init.d) - -* Wed Jul 5 2000 Than Ngo -- add initdir macro to handle the initscript directory -- add a new macro to handle /etc/pam.d/system-auth - -* Thu Jun 29 2000 Nalin Dahyabhai -- enable Kerberos 5 and SSL support -- patch for duplicate profile.h headers - -* Thu Jun 29 2000 Bill Nottingham -- fix init script - -* Tue Jun 27 2000 Bill Nottingham -- rename samba logs (#11606) - -* Mon Jun 26 2000 Bill Nottingham -- initscript munging - -* Fri Jun 16 2000 Bill Nottingham -- configure the swat stuff usefully -- re-integrate some specfile tweaks that got lost somewhere - -* Thu Jun 15 2000 Bill Nottingham -- rebuild to get rid of cups dependency - -* Wed Jun 14 2000 Nalin Dahyabhai -- tweak logrotate configurations to use the PID file in /var/lock/samba - -* Sun Jun 11 2000 Bill Nottingham -- rebuild in new environment - -* Thu Jun 1 2000 Nalin Dahyabhai -- change PAM setup to use system-auth - -* Mon May 8 2000 Bill Nottingham -- fixes for ia64 - -* Sat May 6 2000 Bill Nottingham -- switch to %%configure - -* Wed Apr 26 2000 Nils Philippsen -- version 2.0.7 - -* Sun Mar 26 2000 Florian La Roche -- simplify preun - -* Thu Mar 16 2000 Bill Nottingham -- fix yp_get_default_domain in autoconf -- only link against readline for smbclient -- fix log rotation (#9909) - -* Fri Feb 25 2000 Bill Nottingham -- fix trigger, again. - -* Mon Feb 7 2000 Bill Nottingham -- fix trigger. - -* Fri Feb 4 2000 Bill Nottingham -- turn on quota support - -* Mon Jan 31 2000 Cristian Gafton -- rebuild to fox dependencies -- man pages are compressed - -* Fri Jan 21 2000 Bill Nottingham -- munge post scripts slightly - -* Wed Jan 19 2000 Bill Nottingham -- turn on mmap again. Wheee. -- ship smbmount on alpha - -* Mon Dec 6 1999 Bill Nottingham -- turn off mmap. ;) - -* Wed Dec 1 1999 Bill Nottingham -- change /var/log/samba to 0700 -- turn on mmap support - -* Thu Nov 11 1999 Bill Nottingham -- update to 2.0.6 - -* Fri Oct 29 1999 Bill Nottingham -- add a %defattr for -common - -* Tue Oct 5 1999 Bill Nottingham -- shift some files into -client -- remove /home/samba from package. - -* Tue Sep 28 1999 Bill Nottingham -- initscript oopsie. killproc -HUP, not other way around. - -* Sat Sep 26 1999 Bill Nottingham -- script cleanups. Again. - -* Wed Sep 22 1999 Bill Nottingham -- add a patch to fix dropped reconnection attempts - -* Mon Sep 6 1999 Jeff Johnson -- use cp rather than mv to preserve /etc/services perms (#4938 et al). -- use mktemp to generate /etc/tmp.XXXXXX file name. -- add prereqs on sed/mktemp/killall (need to move killall to /bin). -- fix trigger syntax (i.e. "samba < 1.9.18p7" not "samba < samba-1.9.18p7") - -* Mon Aug 30 1999 Bill Nottingham -- sed "s|nawk|gawk|" /usr/bin/convert_smbpasswd - -* Sat Aug 21 1999 Bill Nottingham -- fix typo in mount.smb - -* Fri Aug 20 1999 Bill Nottingham -- add a %trigger to work around (sort of) broken scripts in - previous releases - -* Mon Aug 16 1999 Bill Nottingham -- initscript munging - -* Mon Aug 9 1999 Bill Nottingham -- add domain parsing to mount.smb - -* Fri Aug 6 1999 Bill Nottingham -- add a -common package, shuffle files around. - -* Fri Jul 23 1999 Bill Nottingham -- add a chmod in %postun so /etc/services & inetd.conf don't become unreadable - -* Wed Jul 21 1999 Bill Nottingham -- update to 2.0.5 -- fix mount.smb - smbmount options changed again......... -- fix postun. oops. -- update some stuff from the samba team's spec file. - -* Fri Jun 18 1999 Bill Nottingham -- split off clients into separate package -- don't run samba by default - -* Mon Jun 14 1999 Bill Nottingham -- fix one problem with mount.smb script -- fix smbpasswd on sparc with a really ugly kludge - -* Thu Jun 10 1999 Dale Lovelace -- fixed logrotate script - -* Tue May 25 1999 Bill Nottingham -- turn of 64-bit locking on 32-bit platforms - -* Thu May 20 1999 Bill Nottingham -- so many releases, so little time -- explicitly uncomment 'printing = bsd' in sample config - -* Tue May 18 1999 Bill Nottingham -- update to 2.0.4a -- fix mount.smb arg ordering - -* Fri Apr 16 1999 Bill Nottingham -- go back to stop/start for restart (-HUP didn't work in testing) - -* Fri Mar 26 1999 Bill Nottingham -- add a mount.smb to make smb mounting a little easier. -- smb filesystems apparently don't work on alpha. Oops. - -* Thu Mar 25 1999 Bill Nottingham -- always create codepages - -* Tue Mar 23 1999 Bill Nottingham -- logrotate changes - -* Sun Mar 21 1999 Cristian Gafton -- auto rebuild in the new build environment (release 3) - -* Fri Mar 19 1999 Preston Brown -- updated init script to use graceful restart (not stop/start) - -* Tue Mar 9 1999 Bill Nottingham -- update to 2.0.3 - -* Thu Feb 18 1999 Bill Nottingham -- update to 2.0.2 - -* Mon Feb 15 1999 Bill Nottingham -- swat swat - -* Tue Feb 9 1999 Bill Nottingham -- fix bash2 breakage in post script - -* Fri Feb 5 1999 Bill Nottingham -- update to 2.0.0 - -* Mon Oct 12 1998 Cristian Gafton -- make sure all binaries are stripped - -* Thu Sep 17 1998 Jeff Johnson -- update to 1.9.18p10. -- fix %triggerpostun. - -* Tue Jul 07 1998 Erik Troan -- updated postun triggerscript to check $0 -- clear /etc/codepages from %preun instead of %postun - -* Mon Jun 08 1998 Erik Troan -- made the %postun script a tad less agressive; no reason to remove - the logs or lock file (after all, if the lock file is still there, - samba is still running) -- the %postun and %preun should only exectute if this is the final - removal -- migrated %triggerpostun from Red Hat's samba package to work around - packaging problems in some Red Hat samba releases - -* Sun Apr 26 1998 John H Terpstra -- minor tidy up in preparation for release of 1.9.18p5 -- added findsmb utility from SGI package +* Fri Jan 16 2004 Gerald (Jerry) Carter +- Removed ChangeLog entries since they are kept in CVS -* Wed Mar 18 1998 John H Terpstra -- Updated version and codepage info. -- Release to test name resolve order -* Sat Jan 24 1998 John H Terpstra -- Many optimisations (some suggested by Manoj Kasichainula -- Use of chkconfig in place of individual symlinks to /etc/rc.d/init/smb -- Compounded make line -- Updated smb.init restart mechanism -- Use compound mkdir -p line instead of individual calls to mkdir -- Fixed smb.conf file path for log files -- Fixed smb.conf file path for incoming smb print spool directory -- Added a number of options to smb.conf file -- Added smbadduser command (missed from all previous RPMs) - Doooh! -- Added smbuser file and smb.conf file updates for username map diff --git a/packaging/Fedora/smb.conf b/packaging/Fedora/smb.conf new file mode 100644 index 0000000000..74806da16b --- /dev/null +++ b/packaging/Fedora/smb.conf @@ -0,0 +1,286 @@ +# This is the main Samba configuration file. You should read the +# smb.conf(5) manual page in order to understand the options listed +# here. Samba has a huge number of configurable options (perhaps too +# many!) most of which are not shown in this example +# +# Any line which starts with a ; (semi-colon) or a # (hash) +# is a comment and is ignored. In this example we will use a # +# for commentry and a ; for parts of the config file that you +# may wish to enable +# +# NOTE: Whenever you modify this file you should run the command "testparm" +# to check that you have not made any basic syntactic errors. +# +#======================= Global Settings ===================================== +[global] + +# workgroup = NT-Domain-Name or Workgroup-Name + workgroup = MYGROUP + +# server string is the equivalent of the NT Description field + server string = Samba Server + +# This option is important for security. It allows you to restrict +# connections to machines which are on your local network. The +# following example restricts access to two C class networks and +# the "loopback" interface. For more examples of the syntax see +# the smb.conf man page +; hosts allow = 192.168.1. 192.168.2. 127. + +# if you want to automatically load your printer list rather +# than setting them up individually then you'll need this + printcap name = /etc/printcap + load printers = yes + +# It should not be necessary to spell out the print system type unless +# yours is non-standard. Currently supported print systems include: +# bsd, sysv, plp, lprng, aix, hpux, qnx +; printing = bsd + +# Uncomment this if you want a guest account, you must add this to /etc/passwd +# otherwise the user "nobody" is used +; guest account = pcguest + +# this tells Samba to use a separate log file for each machine +# that connects + log file = /var/log/samba/log.%m + +# Put a capping on the size of the log files (in Kb). + max log size = 50 + +# Security mode. Most people will want user level security. See +# security_level.txt for details. + security = user +# Use password server option only with security = server +; password server = + +# Password Level allows matching of _n_ characters of the password for +# all combinations of upper and lower case. +; password level = 8 +; username level = 8 + +# You may wish to use password encryption. Please read +# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation. +# Do not enable this option unless you have read those documents +; encrypt passwords = yes +; smb passwd file = /etc/samba/smbpasswd + +# The following are needed to allow password changing from Windows to +# update the Linux system password also. +# NOTE: Use these with 'encrypt passwords' and 'smb passwd file' above. +# NOTE2: You do NOT need these to allow workstations to change only +# the encrypted SMB passwords. They allow the Unix password +# to be kept in sync with the SMB password. +; unix password sync = Yes +; passwd program = /usr/bin/passwd %u +; passwd chat = *New*UNIX*password* %n\n *ReType*new*UNIX*password* %n\n *passwd:*all*authentication*tokens*updated*successfully* + +# Unix users can map to different SMB User names +; username map = /etc/samba/smbusers + +# Using the following line enables you to customise your configuration +# on a per machine basis. The %m gets replaced with the netbios name +# of the machine that is connecting +; include = /etc/samba/smb.conf.%m + +# Most people will find that this option gives better performance. +# See speed.txt and the manual pages for details + socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192 + +# Configure Samba to use multiple interfaces +# If you have multiple network interfaces then you must list them +# here. See the man page for details. +; interfaces = 192.168.12.2/24 192.168.13.2/24 + +# Configure remote browse list synchronisation here +# request announcement to, or browse list sync from: +# a specific host or from / to a whole subnet (see below) +; remote browse sync = 192.168.3.25 192.168.5.255 +# Cause this host to announce itself to local subnets here +; remote announce = 192.168.1.255 192.168.2.44 + +# Browser Control Options: +# set local master to no if you don't want Samba to become a master +# browser on your network. Otherwise the normal election rules apply +; local master = no + +# OS Level determines the precedence of this server in master browser +# elections. The default value should be reasonable +; os level = 33 + +# Domain Master specifies Samba to be the Domain Master Browser. This +# allows Samba to collate browse lists between subnets. Don't use this +# if you already have a Windows NT domain controller doing this job +; domain master = yes + +# Preferred Master causes Samba to force a local browser election on startup +# and gives it a slightly higher chance of winning the election +; preferred master = yes + +# Enable this if you want Samba to be a domain logon server for +# Windows95 workstations. +; domain logons = yes + +# if you enable domain logons then you may want a per-machine or +# per user logon script +# run a specific logon batch file per workstation (machine) +; logon script = %m.bat +# run a specific logon batch file per username +; logon script = %U.bat + +# Where to store roving profiles (only for Win95 and WinNT) +# %L substitutes for this servers netbios name, %U is username +# You must uncomment the [Profiles] share below +; logon path = \\%L\Profiles\%U + +# All NetBIOS names must be resolved to IP Addresses +# 'Name Resolve Order' allows the named resolution mechanism to be specified +# the default order is "host lmhosts wins bcast". "host" means use the unix +# system gethostbyname() function call that will use either /etc/hosts OR +# DNS or NIS depending on the settings of /etc/host.config, /etc/nsswitch.conf +# and the /etc/resolv.conf file. "host" therefore is system configuration +# dependant. This parameter is most often of use to prevent DNS lookups +# in order to resolve NetBIOS names to IP Addresses. Use with care! +# The example below excludes use of name resolution for machines that are NOT +# on the local network segment +# - OR - are not deliberately to be known via lmhosts or via WINS. +; name resolve order = wins lmhosts bcast + +# Windows Internet Name Serving Support Section: +# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server +; wins support = yes + +# WINS Server - Tells the NMBD components of Samba to be a WINS Client +# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both +; wins server = w.x.y.z + +# WINS Proxy - Tells Samba to answer name resolution queries on +# behalf of a non WINS capable client, for this to work there must be +# at least one WINS Server on the network. The default is NO. +; wins proxy = yes + +# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names +# via DNS nslookups. The built-in default for versions 1.9.17 is yes, +# this has been changed in version 1.9.18 to no. + dns proxy = no + +# Case Preservation can be handy - system default is _no_ +# NOTE: These can be set on a per share basis +; preserve case = no +; short preserve case = no +# Default case is normally upper case for all DOS files +; default case = lower +# Be very careful with case sensitivity - it can break things! +; case sensitive = no + +#============================ Share Definitions ============================== +[homes] + comment = Home Directories + browseable = no + writable = yes + +# Un-comment the following and create the netlogon directory for Domain Logons +; [netlogon] +; comment = Network Logon Service +; path = /home/netlogon +; guest ok = yes +; writable = no +; share modes = no + + +# Un-comment the following to provide a specific roving profile share +# the default is to use the user's home directory +;[Profiles] +; path = /home/profiles +; browseable = no +; guest ok = yes + + +# NOTE: If you have a BSD-style print system there is no need to +# specifically define each individual printer +[printers] + comment = All Printers + path = /var/spool/samba + browseable = no +# Set public = yes to allow user 'guest account' to print + guest ok = no + writable = no + printable = yes + +# This one is useful for people to share files +;[tmp] +; comment = Temporary file space +; path = /tmp +; read only = no +; public = yes + +# A publicly accessible directory, but read only, except for people in +# the "staff" group +;[public] +; comment = Public Stuff +; path = /home/samba +; public = yes +; read only = yes +; write list = @staff + +# Other examples. +# +# A private printer, usable only by fred. Spool data will be placed in fred's +# home directory. Note that fred must have write access to the spool directory, +# wherever it is. +;[fredsprn] +; comment = Fred's Printer +; valid users = fred +; path = /homes/fred +; printer = freds_printer +; public = no +; writable = no +; printable = yes + +# A private directory, usable only by fred. Note that fred requires write +# access to the directory. +;[fredsdir] +; comment = Fred's Service +; path = /usr/somewhere/private +; valid users = fred +; public = no +; writable = yes +; printable = no + +# a service which has a different directory for each machine that connects +# this allows you to tailor configurations to incoming machines. You could +# also use the %u option to tailor it by user name. +# The %m gets replaced with the machine name that is connecting. +;[pchome] +; comment = PC Directories +; path = /usr/pc/%m +; public = no +; writable = yes + +# A publicly accessible directory, read/write to all users. Note that all files +# created in the directory by users will be owned by the default user, so +# any user with access can delete any other user's files. Obviously this +# directory must be writable by the default user. Another user could of course +# be specified, in which case all files would be owned by that user instead. +;[public] +; path = /usr/somewhere/else/public +; public = yes +; only guest = yes +; writable = yes +; printable = no + +# The following two entries demonstrate how to share a directory so that two +# users can place files there that will be owned by the specific users. In this +# setup, the directory should be writable by both users and should have the +# sticky bit set on it to prevent abuse. Obviously this could be extended to +# as many users as required. +;[myshare] +; comment = Mary's and Fred's stuff +; path = /usr/somewhere/shared +; valid users = mary fred +; public = no +; writable = yes +; printable = no +; create mask = 0765 + + diff --git a/packaging/Fedora/smb.init b/packaging/Fedora/smb.init index fca823a064..11a011883f 100644 --- a/packaging/Fedora/smb.init +++ b/packaging/Fedora/smb.init @@ -60,14 +60,16 @@ start() { stop() { KIND="SMB" echo -n $"Shutting down $KIND services: " - killproc smbd + killproc smbd -TERM RETVAL=$? + [ $RETVAL -eq 0 ] && rm -f /var/run/smbd.pid echo KIND="NMB" echo -n $"Shutting down $KIND services: " - killproc nmbd + killproc nmbd -TERM RETVAL2=$? - [ $RETVAL -eq 0 -a $RETVAL2 -eq 0 ] && rm -f /var/lock/subsys/smb + [ $RETVAL2 -eq 0 ] && rm -f /var/run/nmbd.pid + [ $RETVAL -eq 0 -a $RETVAL2 -eq 0 ] && rm -f /var/lock/subsys/smb echo "" return $RETVAL } diff --git a/packaging/Fedora/smbusers b/packaging/Fedora/smbusers new file mode 100644 index 0000000000..ae3389f53f --- /dev/null +++ b/packaging/Fedora/smbusers @@ -0,0 +1,3 @@ +# Unix_name = SMB_name1 SMB_name2 ... +root = administrator admin +nobody = guest pcguest smbguest diff --git a/packaging/Fedora/winbind.init b/packaging/Fedora/winbind.init index ced81135b2..05e0eb4d00 100644 --- a/packaging/Fedora/winbind.init +++ b/packaging/Fedora/winbind.init @@ -49,9 +49,11 @@ stop() { echo KIND="Winbind" echo -n $"Shutting down $KIND services: " - killproc winbindd + killproc winbindd -TERM RETVAL=$? - [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/winbindd + [ $RETVAL -eq 0 ] \ + && && rm -f /var/run/nmbd.pid \ + && rm -f /var/lock/subsys/winbindd echo "" return $RETVAL } diff --git a/packaging/RedHat/samba.spec.tmpl b/packaging/RedHat/samba.spec.tmpl index ee0b43c017..787fe87d4a 100644 --- a/packaging/RedHat/samba.spec.tmpl +++ b/packaging/RedHat/samba.spec.tmpl @@ -2,6 +2,7 @@ %define rpm_version `rpm --version | awk '{print $3}' | awk -F. '{print $1$2}'` Summary: Samba SMB client and server +Vendor: Samba Team Name: samba Version: PVERSION Release: PRELEASE @@ -113,7 +114,7 @@ mkdir -p $RPM_BUILD_ROOT%{prefix}/{bin,sbin} mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/{images,help,include,using_samba} mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/using_samba/{figs,gifs} mkdir -p $RPM_BUILD_ROOTMANDIR_MACRO -mkdir -p $RPM_BUILD_ROOT/var/cache/samba +mkdir -p $RPM_BUILD_ROOT/var/lib/samba mkdir -p $RPM_BUILD_ROOT/var/{log,run}/samba mkdir -p $RPM_BUILD_ROOT/var/spool/samba mkdir -p $RPM_BUILD_ROOT/lib/security @@ -192,10 +193,23 @@ echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/etc/samba/lmhosts # Remove "*.old" files find $RPM_BUILD_ROOT -name "*.old" -exec rm -f {} \; +## +## Clean out man pages for tools not installed here +## +rm -f $RPM_BUILD_ROOT/%{_mandir}/man1/editreg.1* +rm -f $RPM_BUILD_ROOT%{_mandir}/man1/log2pcap.1* +rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbsh.1* +rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbget.1* +rm -f $RPM_BUILD_ROOT/%{_mandir}/man8/mount.cifs.8* + + %clean rm -rf $RPM_BUILD_ROOT %post +## +## only needed if this is a new install (not an upgrade) +## if [ "$1" -eq "1" ]; then /sbin/chkconfig --add smb /sbin/chkconfig --add winbind @@ -203,96 +217,85 @@ if [ "$1" -eq "1" ]; then /sbin/chkconfig winbind off fi -echo "Looking for old /etc/smb.conf..." -if [ -f /etc/smb.conf -a ! -f /etc/samba/smb.conf ]; then - echo "Moving old /etc/smb.conf to /etc/samba/smb.conf" - mv /etc/smb.conf /etc/samba/smb.conf -fi - -echo "Looking for old /etc/smbusers..." -if [ -f /etc/smbusers -a ! -f /etc/samba/smbusers ]; then - echo "Moving old /etc/smbusers to /etc/samba/smbusers" - mv /etc/smbusers /etc/samba/smbusers -fi - -echo "Looking for old /etc/lmhosts..." -if [ -f /etc/lmhosts -a ! -f /etc/samba/lmhosts ]; then - echo "Moving old /etc/lmhosts to /etc/samba/lmhosts" - mv /etc/lmhosts /etc/samba/lmhosts -fi - -echo "Looking for old /etc/MACHINE.SID..." -if [ -f /etc/MACHINE.SID -a ! -f /etc/samba/MACHINE.SID ]; then - echo "Moving old /etc/MACHINE.SID to /etc/samba/MACHINE.SID" - mv /etc/MACHINE.SID /etc/samba/MACHINE.SID -fi - -echo "Looking for old /etc/smbpasswd..." -if [ -f /etc/smbpasswd -a ! -f /etc/samba/smbpasswd ]; then - echo "Moving old /etc/smbpasswd to /etc/samba/smbpasswd" - mv /etc/smbpasswd /etc/samba/smbpasswd -fi - -# -# For 2.2.1 we move the tdb files from /var/lock/samba to /var/cache/samba -# to preserve across reboots. -# -echo "Moving tdb files in /var/lock/samba/*.tdb to /var/cache/samba/*.tdb" -for i in /var/lock/samba/*.tdb -do -if [ -f $i ]; then - newname=`echo $i | sed -e's|var\/lock\/samba|var\/cache\/samba|'` - echo "Moving $i to $newname" - mv $i $newname -fi -done +## +## we only have to wory about this if we are upgrading +## +if [ "$1" -eq "2" ]; then + if [ -f /etc/smb.conf -a ! -f /etc/samba/smb.conf ]; then + echo "Moving old /etc/smb.conf to /etc/samba/smb.conf" + mv /etc/smb.conf /etc/samba/smb.conf + fi -# Remove the transient tdb files. -if [ -e /var/cache/samba/brlock.tdb ]; then - rm -f /var/cache/samba/brlock.tdb -fi + if [ -f /etc/smbusers -a ! -f /etc/samba/smbusers ]; then + echo "Moving old /etc/smbusers to /etc/samba/smbusers" + mv /etc/smbusers /etc/samba/smbusers + fi -if [ -e /var/cache/samba/unexpected.tdb ]; then - rm -f /var/cache/samba/unexpected.tdb -fi + if [ -f /etc/lmhosts -a ! -f /etc/samba/lmhosts ]; then + echo "Moving old /etc/lmhosts to /etc/samba/lmhosts" + mv /etc/lmhosts /etc/samba/lmhosts + fi -if [ -e /var/cache/samba/connections.tdb ]; then - rm -f /var/cache/samba/connections.tdb -fi + if [ -f /etc/MACHINE.SID -a ! -f /etc/samba/MACHINE.SID ]; then + echo "Moving old /etc/MACHINE.SID to /etc/samba/MACHINE.SID" + mv /etc/MACHINE.SID /etc/samba/MACHINE.SID + fi -if [ -e /var/cache/samba/locking.tdb ]; then - rm -f /var/cache/samba/locking.tdb -fi + if [ -f /etc/smbpasswd -a ! -f /etc/samba/smbpasswd ]; then + echo "Moving old /etc/smbpasswd to /etc/samba/smbpasswd" + mv /etc/smbpasswd /etc/samba/smbpasswd + fi -if [ -e /var/cache/samba/messages.tdb ]; then - rm -f /var/cache/samba/messages.tdb + # + # For 2.2.1 we move the tdb files from /var/lock/samba to /var/cache/samba + # to preserve across reboots. + # + for i in /var/lock/samba/*.tdb; do + if [ -f $i ]; then + newname="/var/lib/samba/`basename $i`" + echo "Moving $i to $newname" + mv $i $newname + fi + done + + # + # For 3.0.1 we move the tdb files from /var/cache/samba to /var/lib/samba + # + echo "Moving tdb files in /var/cache/samba/*.tdb to /var/lib/samba/*.tdb" + for i in /var/cache/samba/*.tdb; do + if [ -f $i ]; then + newname="/var/lib/samba/`basename $i`" + echo "Moving $i to $newname" + mv $i $newname + fi + done fi -if [ -d /var/lock/samba ]; then - rm -rf /var/lock/samba -fi +## +## New things +## # Add swat entry to /etc/services if not already there. -if !( grep ^[:space:]*swat /etc/services > /dev/null ) then +if [ ! "`grep ^\s**swat /etc/services`" ]; then echo 'swat 901/tcp # Add swat service used via inetd' >> /etc/services fi # Add swat entry to /etc/inetd.conf if needed. if [ -f /etc/inetd.conf ]; then - if !( grep ^[:space:]*swat /etc/inetd.conf > /dev/null ) then + if [ ! "`grep ^\s*swat /etc/inetd.conf`" ]; then echo 'swat stream tcp nowait.400 root %{prefix}/sbin/swat swat' >> /etc/inetd.conf - killall -1 inetd || : + killall -HUP inetd || : fi fi # Add swat entry to xinetd.d if needed. -if [ -d $RPM_BUILD_ROOT/etc/xinetd.d -a ! -f /etc/xinetd.d/swat ]; then +if [ -d /etc/xinetd.d -a ! -f /etc/xinetd.d/swat ]; then mv /etc/samba/samba.xinetd /etc/xinetd.d/swat else rm -f /etc/samba/samba.xinetd fi -# Install the correct version of the samba pam file, depending on pam version. +# Install the correct version of the samba pam file if [ -f /lib/security/pam_stack.so ]; then echo "Installing stack version of /etc/pam.d/samba..." mv /etc/samba/samba.stack /etc/pam.d/samba @@ -305,77 +308,75 @@ fi /sbin/ldconfig %preun -if [ $1 = 0 ] ; then +if [ "$1" -eq "0" ] ; then /sbin/chkconfig --del smb /sbin/chkconfig --del winbind - # We want to remove the browse.dat and wins.dat files so they can not interfer with a new version of samba! - if [ -e /var/cache/samba/browse.dat ]; then - rm -f /var/cache/samba/browse.dat + # We want to remove the browse.dat and wins.dat files + # so they can not interfer with a new version of samba! + if [ -e /var/lib/samba/browse.dat ]; then + rm -f /var/lib/samba/browse.dat fi - if [ -e /var/cache/samba/wins.dat ]; then - rm -f /var/cache/samba/wins.dat + if [ -e /var/lib/samba/wins.dat ]; then + rm -f /var/lib/samba/wins.dat fi # Remove the transient tdb files. - if [ -e /var/cache/samba/brlock.tdb ]; then - rm -f /var/cache/samba/brlock.tdb - fi - - if [ -e /var/cache/samba/unexpected.tdb ]; then - rm -f /var/cache/samba/unexpected.tdb + if [ -e /var/lib/samba/brlock.tdb ]; then + rm -f /var/lib/samba/brlock.tdb fi - if [ -e /var/cache/samba/connections.tdb ]; then - rm -f /var/cache/samba/connections.tdb + if [ -e /var/lib/samba/unexpected.tdb ]; then + rm -f /var/lib/samba/unexpected.tdb fi - if [ -e /var/cache/samba/locking.tdb ]; then - rm -f /var/cache/samba/locking.tdb + if [ -e /var/lib/samba/connections.tdb ]; then + rm -f /var/lib/samba/connections.tdb fi - if [ -e /var/cache/samba/messages.tdb ]; then - rm -f /var/cache/samba/messages.tdb + if [ -e /var/lib/samba/locking.tdb ]; then + rm -f /var/lib/samba/locking.tdb fi - # Remove winbind nss client symlink - - if [ -L /lib/libnss_winbind.so.2 ]; then - rm -f /lib/libnss_winbind.so.2 + if [ -e /var/lib/samba/messages.tdb ]; then + rm -f /var/lib/samba/messages.tdb fi fi %postun # Only delete remnants of samba if this is the final deletion. -if [ $1 = 0 ] ; then +if [ "$1" -eq "0" ] ; then if [ -x /etc/pam.d/samba ]; then rm -f /etc/pam.d/samba fi + if [ -e /var/log/samba ]; then rm -rf /var/log/samba fi - if [ -e /var/cache/samba ]; then - rm -rf /var/cache/samba - fi + + if [ -e /var/lib/samba ]; then + rm -rf /var/lib/samba + fi # Remove swat entries from /etc/inetd.conf and /etc/services cd /etc tmpfile=/etc/tmp.$$ - if [ -f /etc/inetd.conf ]; then + if [ -f /etc/inetd.conf ]; then # preserve inetd.conf permissions. cp -p /etc/inetd.conf $tmpfile sed -e '/^[:space:]*swat.*$/d' /etc/inetd.conf > $tmpfile mv $tmpfile inetd.conf - fi + fi + # preserve services permissions. cp -p /etc/services $tmpfile sed -e '/^[:space:]*swat.*$/d' /etc/services > $tmpfile mv $tmpfile /etc/services - # Remove swat entry from /etc/xinetd.d - if [ -f /etc/xinetd.d/swat ]; then - rm -r /etc/xinetd.d/swat - fi + # Remove swat entry from /etc/xinetd.d + if [ -f /etc/xinetd.d/swat ]; then + rm -r /etc/xinetd.d/swat + fi fi /sbin/ldconfig @@ -447,7 +448,7 @@ MANDIR_MACRO/man1/* MANDIR_MACRO/man5/* MANDIR_MACRO/man7/* MANDIR_MACRO/man8/* -%attr(755,root,root) %dir /var/cache/samba +%attr(755,root,root) %dir /var/lib/samba %dir /var/log/samba %dir /var/run/samba %attr(1777,root,root) %dir /var/spool/samba diff --git a/packaging/SuSE/samba3.spec b/packaging/SuSE/samba3.spec index 1b620e60c2..37d8a4d36f 100644 --- a/packaging/SuSE/samba3.spec +++ b/packaging/SuSE/samba3.spec @@ -14,6 +14,7 @@ # usedforbuild aaa_base acl attr bash bind9-utils bison coreutils cpio cpp cvs cyrus-sasl2 db devs diffutils e2fsprogs file filesystem fillup findutils flex gawk gdbm-devel glibc glibc-devel glibc-locale gpm grep groff gzip info insserv kbd less libacl libattr libgcc libstdc++ libxcrypt m4 make man mktemp modutils ncurses ncurses-devel net-tools netcfg pam pam-devel pam-modules patch permissions ps rcs readline sed sendmail shadow strace syslogd sysvinit tar texinfo timezone unzip util-linux vim zlib zlib-devel XFree86-libs autoconf automake binutils bzip2 cracklib cups-devel cups-libs dialog docbook-utils docbook-xsl-stylesheets docbook_4 ed freetype2 gcc gdbm gettext ghostscript-fonts-std ghostscript-library ghostscript-x11 glib heimdal heimdal-devel heimdal-lib iso_ent libacl-devel libattr-devel libgimpprint libpng libtiff libtool libxml2 libxml2-devel libxslt mysql-devel mysql-shared openldap2 openldap2-client openldap2-devel openssl openssl-devel perl popt popt-devel python python-devel readline-devel rpm te_ams te_etex te_latex te_pdf tetex xmlcharent Name: samba3 +Vendor: Samba Team License: GPL Group: Productivity/Networking/Samba Url: http://www.samba.org diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 97abbd46e3..048a6c5db0 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -701,10 +701,12 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids) { struct group *grp; - struct passwd *pwd; int i=0; char *gr; DOM_SID *s; + + struct sys_pwent *userlist; + struct sys_pwent *user; if(!init_group_mapping()) { DEBUG(0,("failed to initialize group mapping")); @@ -751,41 +753,53 @@ BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids) winbind_off(); - setpwent(); - while ((pwd=getpwent()) != NULL) { - if (pwd->pw_gid==gid) { - SAM_ACCOUNT *group_member_acct = NULL; - BOOL found_user; - s = Realloc((*sids), sizeof(**sids)*(*num_sids+1)); - if (!s) { - DEBUG(0,("get_sid_list_of_group: unable to enlarge SID list!\n")); - winbind_on(); - return False; - } - else (*sids) = s; + user = userlist = getpwent_list(); + + while (user != NULL) { + + SAM_ACCOUNT *group_member_acct = NULL; + BOOL found_user; + + if (user->pw_gid != gid) { + user = user->next; + continue; + } + + s = Realloc((*sids), sizeof(**sids)*(*num_sids+1)); + if (!s) { + DEBUG(0,("get_sid_list_of_group: unable to enlarge " + "SID list!\n")); + pwent_free(userlist); + winbind_on(); + return False; + } + else (*sids) = s; - if (!NT_STATUS_IS_OK(pdb_init_sam(&group_member_acct))) { - continue; - } + if (!NT_STATUS_IS_OK(pdb_init_sam(&group_member_acct))) { + continue; + } - become_root(); - found_user = pdb_getsampwnam(group_member_acct, pwd->pw_name); - unbecome_root(); + become_root(); + found_user = pdb_getsampwnam(group_member_acct, user->pw_name); + unbecome_root(); - if (found_user) { - sid_copy(&(*sids)[*num_sids], pdb_get_user_sid(group_member_acct)); + if (found_user) { + sid_copy(&(*sids)[*num_sids], + pdb_get_user_sid(group_member_acct)); + (*num_sids)++; + } else { + DEBUG(4,("get_sid_list_of_group: User %s [uid == %lu] " + "has no samba account\n", + user->pw_name, (unsigned long)user->pw_uid)); + if (algorithmic_uid_to_sid(&(*sids)[*num_sids], + user->pw_uid)) (*num_sids)++; - } else { - DEBUG(4,("get_sid_list_of_group: User %s [uid == %lu] has no samba account\n", - pwd->pw_name, (unsigned long)pwd->pw_uid)); - if (algorithmic_uid_to_sid(&(*sids)[*num_sids], pwd->pw_uid)) - (*num_sids)++; - } - - pdb_free_sam(&group_member_acct); } + pdb_free_sam(&group_member_acct); + + user = user->next; } - endpwent(); + pwent_free(userlist); DEBUG(10, ("got primary groups, members: [%d]\n", *num_sids)); winbind_on(); diff --git a/source3/nsswitch/winbind_nss_linux.c b/source3/nsswitch/winbind_nss_linux.c index ac4a861ff1..362047f62b 100644 --- a/source3/nsswitch/winbind_nss_linux.c +++ b/source3/nsswitch/winbind_nss_linux.c @@ -1009,3 +1009,141 @@ failed: free_response(&response); return ret; } + +/* map a sid to a uid */ +NSS_STATUS +_nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_response response; + struct winbindd_request request; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: sidtouid %s\n", getpid(), sid); +#endif + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); + request.data.sid[sizeof(request.data.sid) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_SID_TO_UID, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + *uid = response.data.uid; + +failed: + return ret; +} + +/* map a sid to a gid */ +NSS_STATUS +_nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_response response; + struct winbindd_request request; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: sidtogid %s\n", getpid(), sid); +#endif + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); + request.data.sid[sizeof(request.data.sid) - 1] = '\0'; + + ret = winbindd_request(WINBINDD_SID_TO_GID, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + *gid = response.data.gid; + +failed: + return ret; +} + +/* map a uid to a SID string */ +NSS_STATUS +_nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_response response; + struct winbindd_request request; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: uidtosid %s\n", getpid(), name); +#endif + + ZERO_STRUCT(response); + ZERO_STRUCT(request); + + request.data.uid = uid; + + ret = winbindd_request(WINBINDD_UID_TO_SID, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + if (buflen < strlen(response.data.sid.sid)+1) { + ret = NSS_STATUS_TRYAGAIN; + *errnop = errno = ERANGE; + goto failed; + } + + *errnop = errno = 0; + *sid = buffer; + strcpy(*sid, response.data.sid.sid); + +failed: + free_response(&response); + return ret; +} + +/* map a gid to a SID string */ +NSS_STATUS +_nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer, + size_t buflen, int *errnop) +{ + NSS_STATUS ret; + struct winbindd_response response; + struct winbindd_request request; + +#ifdef DEBUG_NSS + fprintf(stderr, "[%5d]: gidtosid %s\n", getpid(), name); +#endif + + ZERO_STRUCT(response); + ZERO_STRUCT(request); + + request.data.gid = gid; + + ret = winbindd_request(WINBINDD_GID_TO_SID, &request, &response); + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno = EINVAL; + goto failed; + } + + if (buflen < strlen(response.data.sid.sid)+1) { + ret = NSS_STATUS_TRYAGAIN; + *errnop = errno = ERANGE; + goto failed; + } + + *errnop = errno = 0; + *sid = buffer; + strcpy(*sid, response.data.sid.sid); + +failed: + free_response(&response); + return ret; +} diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index b31dc92b38..4805e628dd 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -1098,7 +1098,7 @@ enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state) enum winbindd_result result = WINBINDD_ERROR; unsigned int i; TALLOC_CTX *mem_ctx; - char *ret; + char *ret = NULL; uint32 num_groups; unsigned ofs, ret_size = 0; @@ -1144,7 +1144,7 @@ enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state) ofs = 0; for (i = 0; i < num_groups; i++) { const char *s = sid_string_static(user_grpsids[i]); - safe_strcpy(ret + ofs, s, ret_size - ofs); + safe_strcpy(ret + ofs, s, ret_size - ofs - 1); ofs += strlen(ret+ofs) + 1; } diff --git a/source3/rpc_parse/parse_epmapper.c b/source3/rpc_parse/parse_epmapper.c index 89dc0994c6..bc2cd17503 100644 --- a/source3/rpc_parse/parse_epmapper.c +++ b/source3/rpc_parse/parse_epmapper.c @@ -45,37 +45,37 @@ BOOL epm_io_handle(const char *desc, EPM_HANDLE *handle, prs_struct *ps, /******************************************************************* inits an EPM_FLOOR structure. ********************************************************************/ -NTSTATUS init_epm_floor(EPM_FLOOR *floor, uint8 protocol) +NTSTATUS init_epm_floor(EPM_FLOOR *efloor, uint8 protocol) { /* handle lhs */ - floor->lhs.protocol = protocol; - floor->lhs.length = sizeof(floor->lhs.protocol); + efloor->lhs.protocol = protocol; + efloor->lhs.length = sizeof(efloor->lhs.protocol); - switch(floor->lhs.protocol) { + switch(efloor->lhs.protocol) { case EPM_FLOOR_UUID: - floor->lhs.length += sizeof(floor->lhs.uuid.uuid); - floor->lhs.length += sizeof(floor->lhs.uuid.version); + efloor->lhs.length += sizeof(efloor->lhs.uuid.uuid); + efloor->lhs.length += sizeof(efloor->lhs.uuid.version); break; default: break; } /* handle rhs */ - switch(floor->lhs.protocol) { + switch(efloor->lhs.protocol) { case EPM_FLOOR_RPC: case EPM_FLOOR_UUID: - floor->rhs.length = sizeof(floor->rhs.unknown); + efloor->rhs.length = sizeof(efloor->rhs.unknown); break; case EPM_FLOOR_TCP: - floor->rhs.length = sizeof(floor->rhs.tcp.port); + efloor->rhs.length = sizeof(efloor->rhs.tcp.port); break; case EPM_FLOOR_IP: - floor->rhs.length = sizeof(floor->rhs.ip.addr); + efloor->rhs.length = sizeof(efloor->rhs.ip.addr); break; case EPM_FLOOR_NMPIPES: case EPM_FLOOR_LRPC: case EPM_FLOOR_NETBIOS: - floor->rhs.length = strlen(floor->rhs.string) + 1; + efloor->rhs.length = strlen(efloor->rhs.string) + 1; break; default: break; @@ -87,118 +87,118 @@ NTSTATUS init_epm_floor(EPM_FLOOR *floor, uint8 protocol) /******************************************************************* inits an EPM_FLOOR structure with a UUID ********************************************************************/ -NTSTATUS init_epm_floor_uuid(EPM_FLOOR *floor, +NTSTATUS init_epm_floor_uuid(EPM_FLOOR *efloor, const struct uuid uuid, uint16 version) { - memcpy(&floor->lhs.uuid.uuid, &uuid, sizeof(uuid)); - floor->lhs.uuid.version = version; - floor->rhs.unknown = 0; - return init_epm_floor(floor, EPM_FLOOR_UUID); + memcpy(&efloor->lhs.uuid.uuid, &uuid, sizeof(uuid)); + efloor->lhs.uuid.version = version; + efloor->rhs.unknown = 0; + return init_epm_floor(efloor, EPM_FLOOR_UUID); } /******************************************************************* inits an EPM_FLOOR structure for RPC ********************************************************************/ -NTSTATUS init_epm_floor_rpc(EPM_FLOOR *floor) +NTSTATUS init_epm_floor_rpc(EPM_FLOOR *efloor) { - floor->rhs.unknown = 0; - return init_epm_floor(floor, EPM_FLOOR_RPC); + efloor->rhs.unknown = 0; + return init_epm_floor(efloor, EPM_FLOOR_RPC); } /******************************************************************* inits an EPM_FLOOR structure for TCP ********************************************************************/ -NTSTATUS init_epm_floor_tcp(EPM_FLOOR *floor, uint16 port) +NTSTATUS init_epm_floor_tcp(EPM_FLOOR *efloor, uint16 port) { - floor->rhs.tcp.port = htons(port); - return init_epm_floor(floor, EPM_FLOOR_TCP); + efloor->rhs.tcp.port = htons(port); + return init_epm_floor(efloor, EPM_FLOOR_TCP); } /******************************************************************* inits an EPM_FLOOR structure for IP ********************************************************************/ -NTSTATUS init_epm_floor_ip(EPM_FLOOR *floor, uint8 addr[4]) +NTSTATUS init_epm_floor_ip(EPM_FLOOR *efloor, uint8 addr[4]) { - memcpy(&floor->rhs.ip.addr, addr, sizeof(addr)); - return init_epm_floor(floor, EPM_FLOOR_IP); + memcpy(&efloor->rhs.ip.addr, addr, sizeof(addr)); + return init_epm_floor(efloor, EPM_FLOOR_IP); } /******************************************************************* inits an EPM_FLOOR structure for named pipe ********************************************************************/ -NTSTATUS init_epm_floor_np(EPM_FLOOR *floor, const char *pipe_name) +NTSTATUS init_epm_floor_np(EPM_FLOOR *efloor, const char *pipe_name) { - safe_strcpy(floor->rhs.string, pipe_name, sizeof(floor->rhs.string)-1); - return init_epm_floor(floor, EPM_FLOOR_NMPIPES); + safe_strcpy(efloor->rhs.string, pipe_name, sizeof(efloor->rhs.string)-1); + return init_epm_floor(efloor, EPM_FLOOR_NMPIPES); } /******************************************************************* inits an EPM_FLOOR structure for named pipe ********************************************************************/ -NTSTATUS init_epm_floor_lrpc(EPM_FLOOR *floor, const char *pipe_name) +NTSTATUS init_epm_floor_lrpc(EPM_FLOOR *efloor, const char *pipe_name) { - safe_strcpy(floor->rhs.string, pipe_name, sizeof(floor->rhs.string)-1); - return init_epm_floor(floor, EPM_FLOOR_LRPC); + safe_strcpy(efloor->rhs.string, pipe_name, sizeof(efloor->rhs.string)-1); + return init_epm_floor(efloor, EPM_FLOOR_LRPC); } /******************************************************************* inits an EPM_FLOOR structure for named pipe ********************************************************************/ -NTSTATUS init_epm_floor_nb(EPM_FLOOR *floor, char *host_name) +NTSTATUS init_epm_floor_nb(EPM_FLOOR *efloor, char *host_name) { - safe_strcpy(floor->rhs.string, host_name, sizeof(floor->rhs.string)-1); - return init_epm_floor(floor, EPM_FLOOR_NETBIOS); + safe_strcpy(efloor->rhs.string, host_name, sizeof(efloor->rhs.string)-1); + return init_epm_floor(efloor, EPM_FLOOR_NETBIOS); } /******************************************************************* reads and writes EPM_FLOOR. ********************************************************************/ -BOOL epm_io_floor(const char *desc, EPM_FLOOR *floor, +BOOL epm_io_floor(const char *desc, EPM_FLOOR *efloor, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "epm_io_floor"); depth++; - if (!prs_uint16("lhs_length", ps, depth, &floor->lhs.length)) + if (!prs_uint16("lhs_length", ps, depth, &efloor->lhs.length)) return False; - if (!prs_uint8("protocol", ps, depth, &floor->lhs.protocol)) + if (!prs_uint8("protocol", ps, depth, &efloor->lhs.protocol)) return False; - switch (floor->lhs.protocol) { + switch (efloor->lhs.protocol) { case EPM_FLOOR_UUID: - if (!smb_io_uuid("uuid", &floor->lhs.uuid.uuid, ps, depth)) + if (!smb_io_uuid("uuid", &efloor->lhs.uuid.uuid, ps, depth)) return False; if (!prs_uint16("version", ps, depth, - &floor->lhs.uuid.version)) + &efloor->lhs.uuid.version)) return False; break; } - if (!prs_uint16("rhs_length", ps, depth, &floor->rhs.length)) + if (!prs_uint16("rhs_length", ps, depth, &efloor->rhs.length)) return False; - switch (floor->lhs.protocol) { + switch (efloor->lhs.protocol) { case EPM_FLOOR_UUID: case EPM_FLOOR_RPC: - if (!prs_uint16("unknown", ps, depth, &floor->rhs.unknown)) + if (!prs_uint16("unknown", ps, depth, &efloor->rhs.unknown)) return False; break; case EPM_FLOOR_TCP: - if (!prs_uint16("tcp_port", ps, depth, &floor->rhs.tcp.port)) + if (!prs_uint16("tcp_port", ps, depth, &efloor->rhs.tcp.port)) return False; break; case EPM_FLOOR_IP: if (!prs_uint8s(False, "ip_addr", ps, depth, - floor->rhs.ip.addr, - sizeof(floor->rhs.ip.addr))) + efloor->rhs.ip.addr, + sizeof(efloor->rhs.ip.addr))) return False; break; case EPM_FLOOR_NMPIPES: case EPM_FLOOR_LRPC: case EPM_FLOOR_NETBIOS: if (!prs_uint8s(False, "string", ps, depth, - floor->rhs.string, - floor->rhs.length)) + efloor->rhs.string, + efloor->rhs.length)) return False; break; default: diff --git a/swat/lang/ja/help/welcome.html b/swat/lang/ja/help/welcome.html index fee6d2084a..240ad22cef 100644 --- a/swat/lang/ja/help/welcome.html +++ b/swat/lang/ja/help/welcome.html @@ -1,86 +1,69 @@ -

SWAT : Samba Web Administration Tool !

- -

Samba‚ÌÝ’è‚Íã‚̃{ƒ^ƒ“‚ðƒNƒŠƒbƒN‚µ‚Äs‚¢‚Ü‚·B

- -

ƒhƒLƒ…ƒƒ“ƒg

- - - -

ƒtƒB[ƒhƒoƒbƒN

- -

“ú–{Œê‰»‚ÉŠÖ‚·‚邱‚Æ‚ÍA SambaƒeƒNƒjƒJƒ‹ƒ[ƒŠƒ“ƒOƒŠƒXƒg‚Ü‚Å‚¨Šè‚¢‚µ‚Ü‚·B

+

SWAT ‚ւ悤‚±‚»!

+ +ã‚̃{ƒ^ƒ“‚ðƒNƒŠƒbƒN‚µ‚ÄÝ’è‚ðs‚Á‚Ä‚­‚¾‚³‚¢B + +

Samba ƒhƒLƒ…ƒƒ“ƒg

+ +
    +
  • ƒf[ƒ‚ƒ“ +
      +
    • smbd - SMB ƒf[ƒ‚ƒ“ +
    • nmbd - NetBIOS ƒl[ƒ€ƒT[ƒo +
    • winbindd - winbind ƒf[ƒ‚ƒ“ +
    +
  • Ý’èƒtƒ@ƒCƒ‹ +
      +
    • smb.conf - Samba Ý’èƒtƒ@ƒCƒ‹ +
    • lmhosts - NetBIOS ‚Ì hosts ƒtƒ@ƒCƒ‹ +
    • smbpasswd - SMB ƒpƒXƒ[ƒhƒtƒ@ƒCƒ‹ +
    +
  • ŠÇ—ƒ†[ƒeƒBƒŠƒeƒB +
      +
    • smbcontrol - Samba ƒf[ƒ‚ƒ“‚ւ̃Rƒ“ƒgƒ[ƒ‹ƒƒbƒZ[ƒW‚Ì‘—o +
    • smbpasswd - SMB ƒpƒXƒ[ƒh‚ÌŠÇ— +
    • SWAT - Web Ý’èƒc[ƒ‹ +
    • net - Samba ‚¨‚æ‚уŠƒ‚[ƒg‚Ì CIFS ƒT[ƒo‚ÌŠÇ—ƒc[ƒ‹ +
    • pdbedit - Samba ‚̃†[ƒUƒAƒJƒEƒ“ƒgŠÇ—ƒc[ƒ‹ +
    • tdbbackup - TDB ƒf[ƒ^ƒx[ƒX‚̃oƒbƒNƒAƒbƒvƒc[ƒ‹ +
    +
  • ƒNƒ‰ƒCƒAƒ“ƒgƒc[ƒ‹ +
      +
    • rpcclient - ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“‚Ì MS-RPC ƒNƒ‰ƒCƒAƒ“ƒg +
    • smbtar - SMB ƒoƒbƒNƒAƒbƒvƒc[ƒ‹ +
    • smbclient - ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“‚Ì SMB ƒNƒ‰ƒCƒAƒ“ƒg +
    • smbmnt - Linux ã‚Ì SMB ƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€‚ðƒ}ƒEƒ“ƒg‚·‚éۂ̕╃c[ƒ‹ +
    • smbmount - Linux ‚É‚¨‚¯‚é SMB ƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€‚̃}ƒEƒ“ƒg‚ðŽÀŒ»‚·‚郆[ƒU‹óŠÔ‚̃c[ƒ‹ +
    • smbspool - ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“‚Ì SMB ˆóüƒNƒ‰ƒCƒAƒ“ƒg +
    • smbumount - Linux ‚É‚¨‚¯‚é SMB ƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€‚̃Aƒ“ƒ}ƒEƒ“ƒg‚ðŽÀŒ»‚·‚郆[ƒU‹óŠÔ‚̃c[ƒ‹ +
    • ntlm_auth - •ÊƒvƒƒOƒ‰ƒ€‚©‚ç‚Ì NTLM ”FØ‚ÌŽg—p‚ðŽÀŒ» +
    • smbcquotas - NTFS 5 ‹¤—L‚̃NƒH[ƒ^î•ñ‚ÌÝ’è‚Ǝ擾 +
    • smbsh - UNIX ƒVƒFƒ‹‚ð—p‚¢‚½ƒŠƒ‚[ƒg SMB ‹¤—L‚ւ̃AƒNƒZƒX‚ðŽÀŒ» +
    • smbtree - ƒeƒLƒXƒgƒx[ƒX‚Ì SMB ƒlƒbƒgƒ[ƒNƒuƒ‰ƒEƒWƒ“ƒO +
    • smbspool - ˆóüƒWƒ‡ƒu‚ð SMB ƒvƒŠƒ“ƒ^‚É‘—M +
    +
  • f’fƒ†[ƒeƒBƒŠƒeƒB +
      +
    • smbstatus - Samba ‚ÌŠÄŽ‹ +
    • testparm - Ý’èƒtƒ@ƒCƒ‹‚Ì®‡«‚ÌŒŸ¸ +
    • testprns - ƒvƒŠƒ“ƒ^Ý’è‚ÌŒŸ¸ +
    • nmblookup - NetBIOS –¼‚ÌŒŸõƒc[ƒ‹ +
    • wbinfo - winbind î•ñ‚̎擾ƒc[ƒ‹ +
    +
  • ‚»‚Ì‘¼‚̃†[ƒeƒBƒŠƒeƒB +
      +
    • profiles - •ÊƒhƒƒCƒ“‚ւ̃vƒƒtƒ@ƒCƒ‹‚̈Ús +
    • editreg - Windows ƒŒƒWƒXƒgƒŠƒtƒ@ƒCƒ‹‚Ì•ÒW +
    • log2pcap - Samba ‚̃ƒOƒtƒ@ƒCƒ‹‚©‚ç pcap ƒtƒ@ƒCƒ‹‚̶¬ +
    +
  • ‘Ð + +
+ +

ƒtƒB[ƒhƒoƒbƒN

+ + ‚±‚̃o[ƒWƒ‡ƒ“‚Ì SWAT ‚ÉŠÖ‚·‚é–â‘è‚ɂ‚¢‚Ä‚Ì‹c˜_‚ðs‚È‚¢‚½‚¢•û‚ÍA + samba ƒ[ƒŠƒ“ƒOƒŠƒXƒg‚Ö‚ÌŽQ‰Á‚ð‚¨Šè‚¢‚µ‚Ü‚·B +(‚à‚µ‚­‚Í sugj-tech ƒ[ƒŠƒ“ƒOƒŠƒXƒg‚É“ú–{Œê‚Å‚¨Šè‚¢‚µ‚Ü‚·) -- cgit From 1323da8e52259716c5b8d403ab795266bb1e590f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 2 Feb 2004 07:54:43 +0000 Subject: Remove bogus check. Cosmetics. Volker (This used to be commit 3768b64c81879231a88c0f3235bfe8ecf29f3af8) --- source3/auth/auth_domain.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 73e0ae7949..fdff0b52f9 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -107,11 +107,6 @@ machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli))); fstr_sprintf((*cli)->mach_acct, "%s$", setup_creds_as); - if (!(*cli)->mach_acct) { - release_server_mutex(); - return NT_STATUS_NO_MEMORY; - } - /* This must be the remote domain (not ours) for schannel */ fstrcpy( (*cli)->domain, domain ); -- cgit From 4ddc620f6b9445d32c3831b2009bd0db784b41a7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 2 Feb 2004 07:58:06 +0000 Subject: (merge from 3.0) Remove duplicate comment. Andrew Bartlett (This used to be commit 841766bcbddbbe5e18d1b7989e54c85ab97715f5) --- source3/nsswitch/winbindd_pam.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index adbcd85435..37b2a9f21b 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -314,8 +314,6 @@ 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? */ - /* what domain should we contact? */ -- cgit From 9e460df0b99b4b7a74dc58bfd0b8a49918de7abd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 2 Feb 2004 21:32:35 +0000 Subject: Merge from 3.0. Jeremy. (This used to be commit 5c5545bd44cdaf4a0b75b0c1c22dd74bb278a6a5) --- source3/nsswitch/winbind_nss_linux.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/nsswitch/winbind_nss_linux.c b/source3/nsswitch/winbind_nss_linux.c index 362047f62b..ae2bcc7ade 100644 --- a/source3/nsswitch/winbind_nss_linux.c +++ b/source3/nsswitch/winbind_nss_linux.c @@ -38,7 +38,7 @@ extern int winbindd_fd; are the pointers passed in by the C library to the _nss_ntdom_* functions. */ -static char *get_static(char **buffer, int *buflen, int len) +static char *get_static(char **buffer, size_t *buflen, size_t len) { char *result; @@ -1080,7 +1080,7 @@ _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer, struct winbindd_request request; #ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: uidtosid %s\n", getpid(), name); + fprintf(stderr, "[%5u]: uidtosid %u\n", (unsigned int)getpid(), (unsigned int)uid); #endif ZERO_STRUCT(response); @@ -1119,7 +1119,7 @@ _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer, struct winbindd_request request; #ifdef DEBUG_NSS - fprintf(stderr, "[%5d]: gidtosid %s\n", getpid(), name); + fprintf(stderr, "[%5u]: gidtosid %u\n", (unsigned int)getpid(), (unsigned int)gid); #endif ZERO_STRUCT(response); -- cgit From bf4e3726fa57cccd10b0fb367cbd17da156fe15c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 Feb 2004 03:23:15 +0000 Subject: Fix for a bug where the mutex could be left locked. Also remove the memory keytab code which has no effect. Driven by bug report from "Rob J. Caskey" . Jeremy. (This used to be commit 2a8601d0bfa35f4d0ccd7946d483473fd10e19d0) --- source3/configure.in | 22 ------ source3/libads/kerberos_verify.c | 154 ++------------------------------------- 2 files changed, 8 insertions(+), 168 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index af6836f060..38f908007c 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2735,28 +2735,6 @@ if test x"$with_ads_support" != x"no"; then [Whether krb5_princ_component is available]) fi - AC_CACHE_CHECK([for memory keytab support], - samba_cv_HAVE_MEMORY_KEYTAB,[ - AC_TRY_RUN([ -#include - main() - { - krb5_context context; - krb5_keytab keytab; - - krb5_init_context(&context); - if (krb5_kt_resolve(context, "MEMORY:", &keytab)) - exit(1); - exit(0); - }], - samba_cv_HAVE_MEMORY_KEYTAB=yes, - samba_cv_HAVE_MEMORY_KEYTAB=no)]) - - if test x"$samba_cv_HAVE_MEMORY_KEYTAB" = x"yes"; then - AC_DEFINE(HAVE_MEMORY_KEYTAB,1, - [Whether in-memory keytabs are supported]) - fi - AC_CACHE_CHECK([for key in krb5_keytab_entry], samba_cv_HAVE_KRB5_KEYTAB_ENTRY_KEY,[ AC_TRY_COMPILE([#include ], diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 50e6971815..47559c1abb 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -26,135 +26,6 @@ #ifdef HAVE_KRB5 -static void free_keytab(krb5_context context, krb5_keytab keytab) -{ - int ret=0; - - if (keytab) - ret = krb5_kt_close(context, keytab); - if (ret) { - DEBUG(3, ("krb5_kt_close failed (%s)\n", - error_message(ret))); - } -} - -#ifdef HAVE_MEMORY_KEYTAB -static krb5_error_code create_keytab(krb5_context context, - krb5_principal host_princ, - char *host_princ_s, - krb5_data password, - krb5_enctype *enctypes, - krb5_keytab *keytab, - char *keytab_name) -{ - krb5_keytab_entry entry; - krb5_kvno kvno = 1; - krb5_error_code ret; - krb5_keyblock *key; - int i; - - DEBUG(10,("creating keytab: %s\n", keytab_name)); - ret = krb5_kt_resolve(context, keytab_name, keytab); - if (ret) - return ret; - - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - return ENOMEM; - } - - /* add keytab entries for all encryption types */ - for ( i=0; enctypes[i]; i++ ) { - - if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) { - continue; - } - - entry.principal = host_princ; - entry.vno = kvno; - -#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) -#error krb5_keytab_entry has no key or keyblock member -#endif - -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */ - entry.key = *key; -#endif - -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */ - entry.keyblock = *key; -#endif - - DEBUG(10,("adding keytab-entry for (%s) with encryption type (%d)\n", - host_princ_s, enctypes[i])); - ret = krb5_kt_add_entry(context, *keytab, &entry); - if (ret) { - DEBUG(1,("adding entry to keytab failed (%s)\n", - error_message(ret))); - free_keytab(context, *keytab); - return ret; - } - } - krb5_free_keyblock(context, key); - - return 0; -} -#endif - -static BOOL setup_keytab(krb5_context context, - krb5_principal host_princ, - char *host_princ_s, - krb5_data password, - krb5_enctype *enctypes, - krb5_keytab *keytab) -{ - char *keytab_name = NULL; - krb5_error_code ret; - - /* check if we have to setup a keytab - not currently enabled - I've put this in so that the else block below functions - the same way that it will when this code is turned on */ - if (0 /* will later be *lp_keytab() */) { - - /* use a file-keytab */ - asprintf(&keytab_name, "%s:%s", - "" - /* KRB5_KT_FILE_PREFIX, "FILE" or - "WRFILE" depending on HEeimdal or MIT */, - "" /* will later be lp_keytab() */); - - DEBUG(10,("will use filebased keytab: %s\n", keytab_name)); - ret = krb5_kt_resolve(context, keytab_name, keytab); - if (ret) { - DEBUG(3,("cannot resolve keytab name %s (%s)\n", - keytab_name, - error_message(ret))); - SAFE_FREE(keytab_name); - return False; - } - - } - -#if defined(HAVE_MEMORY_KEYTAB) - else { - - /* setup a in-memory-keytab */ - asprintf(&keytab_name, "MEMORY:"); - - ret = create_keytab(context, host_princ, host_princ_s, password, enctypes, - keytab, keytab_name); - if (ret) { - DEBUG(3,("unable to create MEMORY: keytab (%s)\n", - error_message(ret))); - SAFE_FREE(keytab_name); - return False; - } - } -#endif - SAFE_FREE(keytab_name); - return True; -} - - /* verify an incoming ticket and parse out the principal name and authorization_data if available @@ -167,7 +38,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, NTSTATUS sret = NT_STATUS_LOGON_FAILURE; krb5_context context = NULL; krb5_auth_context auth_context = NULL; - krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; krb5_rcache rcache = NULL; @@ -177,6 +47,7 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, krb5_principal host_princ; char *host_princ_s = NULL; BOOL free_host_princ = False; + BOOL got_replay_mutex = False; fstring myname; char *password_s = NULL; @@ -280,13 +151,8 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, goto out; } - if (!setup_keytab(context, host_princ, host_princ_s, password, - enctypes, &keytab)) { - DEBUG(3,("ads_verify_ticket: unable to setup keytab\n")); - sret = NT_STATUS_LOGON_FAILURE; - goto out; - } - + got_replay_mutex = True; + /* We need to setup a auth context with each possible encoding type in turn. */ for (i=0;enctypes[i];i++) { if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { @@ -306,12 +172,8 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, packet.data = (krb5_pointer)ticket->data; if (!(ret = krb5_rd_req(context, &auth_context, &packet, -#ifdef HAVE_MEMORY_KEYTAB - host_princ, -#else NULL, -#endif - keytab, NULL, &tkt))) { + NULL, NULL, &tkt))) { DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n", (unsigned int)enctypes[i] )); auth_ok = True; @@ -324,6 +186,7 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, } release_server_mutex(); + got_replay_mutex = False; if (!auth_ok) { DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", @@ -366,10 +229,6 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, } #endif - - /* get rid of all resources associated with the keytab */ - if (keytab) free_keytab(context, keytab); - if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt), principal))) { DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n", @@ -382,6 +241,9 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, out: + if (got_replay_mutex) + release_server_mutex(); + if (!NT_STATUS_IS_OK(sret)) data_blob_free(auth_data); -- cgit From 44c5f5bcc4dffed9d5b468402673070bc1fa554f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Feb 2004 02:09:43 +0000 Subject: Working on #830. Cope with bad conversions better - don't just memcpy but try a crap conversion instead. Next this needs to be done to the convert_alloc function. Actually fixes some valgrind warnings as well - cool ! Jeremy. (This used to be commit 98e2c6f4f854065c56a73ebc9e0a50e0ba018dde) --- source3/lib/charcnv.c | 92 +++++++++++++++++++++++++++++++++++++++++++++------ source3/lib/iconv.c | 1 - 2 files changed, 82 insertions(+), 11 deletions(-) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 5f9392b620..5bd58e3031 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -184,14 +184,18 @@ static size_t convert_string_internal(charset_t from, charset_t to, } } + if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { if (!conv_silent) DEBUG(0,("convert_string_internal: Conversion not supported.\n")); - goto use_as_is; + return 0; } i_len=srclen; o_len=destlen; + + again: + retval = smb_iconv(descriptor, (char **)&inbuf, &i_len, &outbuf, &o_len); if(retval==(size_t)-1) { const char *reason="unknown error"; @@ -227,12 +231,76 @@ static size_t convert_string_internal(charset_t from, charset_t to, use_as_is: - /* conversion not supported, use as is */ + /* + * Conversion not supported. This is actually an error, but there are so + * many misconfigured iconv systems and smb.conf's out there we can't just + * fail. Do a very bad conversion instead.... JRA. + */ + { - size_t len = MIN(srclen,destlen); - if (len) - memcpy(dest,src,len); - return len; + if (o_len == 0 || i_len == 0) + return destlen - o_len; + + if (from == CH_UCS2 && to != CH_UCS2) { + /* Can't convert from ucs2 to multibyte. Just truncate this char to ascii. */ + if (i_len < 2) + return destlen - o_len; + if (i_len >= 2) { + *outbuf = inbuf[0]; + + outbuf++; + o_len--; + + inbuf += 2; + i_len -= 2; + } + + if (o_len == 0 || i_len == 0) + return destlen - o_len; + + /* Keep trying with the next char... */ + goto again; + + } else if (from != CH_UCS2 && to == CH_UCS2) { + /* Can't convert to ucs2 - just widen by adding zero. */ + if (o_len < 2) + return destlen; + outbuf[0] = inbuf[0]; + outbuf[1] = '\0'; + + inbuf++; + i_len--; + + outbuf += 2; + o_len -= 2; + + if (o_len == 0 || i_len == 0) + return destlen - o_len; + + /* Keep trying with the next char... */ + goto again; + + } else if (from != CH_UCS2 && to != CH_UCS2) { + /* Failed multibyte to multibyte. Just copy 1 char and + try again. */ + outbuf[0] = inbuf[0]; + + inbuf++; + i_len--; + + outbuf++; + o_len--; + + if (o_len == 0 || i_len == 0) + return destlen - o_len; + + /* Keep trying with the next char... */ + goto again; + + } else { + /* Keep compiler happy.... */ + return destlen - o_len; + } } } @@ -241,9 +309,9 @@ static size_t convert_string_internal(charset_t from, charset_t to, * Fast path version - handles ASCII first. * * @param src pointer to source string (multibyte or singlebyte) - * @param srclen length of the source string in bytes + * @param srclen length of the source string in bytes, or -1 for nul terminated. * @param dest pointer to destination string (multibyte or singlebyte) - * @param destlen maximal length allowed for string + * @param destlen maximal length allowed for string - *NEVER* -1. * @returns the number of bytes occupied in the destination * * Ensure the srclen contains the terminating zero. @@ -257,11 +325,15 @@ size_t convert_string(charset_t from, charset_t to, void *dest, size_t destlen) { /* - * NB. We deliberately don't do a strlen here is srclen == -1. + * NB. We deliberately don't do a strlen here if srclen == -1. * This is very expensive over millions of calls and is taken * care of in the slow path in convert_string_internal. JRA. */ +#ifdef DEVELOPER + SMB_ASSERT(destlen != (size_t)-1); +#endif + if (srclen == 0) return 0; @@ -302,7 +374,7 @@ size_t convert_string(charset_t from, charset_t to, unsigned char lastp; /* If all characters are ascii, fast path here. */ - while ((slen >= 2) && dlen) { + while (((slen == (size_t)-1) || (slen >= 2)) && dlen) { if (((lastp = *p) <= 0x7f) && (p[1] == 0)) { *q++ = *p; if (slen != (size_t)-1) { diff --git a/source3/lib/iconv.c b/source3/lib/iconv.c index b0c13a5ee6..d0d2dcd1c4 100644 --- a/source3/lib/iconv.c +++ b/source3/lib/iconv.c @@ -589,4 +589,3 @@ toobig: errno = E2BIG; return -1; } - -- cgit From bc056bcb5fd999b3b24572a7b63b666d5b1e49fc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 4 Feb 2004 11:14:44 +0000 Subject: (merge from 3.0) Ensure the remote_password_change() gets a valid prototype from proto.h Andrew Bartlett (This used to be commit 765757b3573b75a3df09d6130b025049d9c93e14) --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 9f26e13421..72b8e33145 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -599,7 +599,7 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \ $(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \ $(RPC_LSA_DS_OBJ) $(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) \ $(RPC_SPOOLSS_OBJ) $(RPC_ECHO_OBJ) $(RPC_EPMAPPER_OBJ) \ - $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o + $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o libsmb/passchange.o WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) \ $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ) -- cgit From d575286894afc1db2ba54324229e44d6c116d878 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Feb 2004 19:13:43 +0000 Subject: Fixup the allocate version of the function to do "crap" conversions too. Embarrassing number of goto's in this :-(. Fixes #830 I think. Jeremy. (This used to be commit e8c7d1c5dca63720b7de6360cb0cff4bed0be546) --- source3/lib/charcnv.c | 103 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 20 deletions(-) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 5bd58e3031..f96d37bccc 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -264,7 +264,8 @@ static size_t convert_string_internal(charset_t from, charset_t to, } else if (from != CH_UCS2 && to == CH_UCS2) { /* Can't convert to ucs2 - just widen by adding zero. */ if (o_len < 2) - return destlen; + return destlen - o_len; + outbuf[0] = inbuf[0]; outbuf[1] = '\0'; @@ -442,6 +443,9 @@ size_t convert_string(charset_t from, charset_t to, * @returns Size in bytes of the converted string; or -1 in case of error. * * Ensure the srclen contains the terminating zero. + * + * I hate the goto's in this function. It's embarressing..... + * There has to be a cleaner way to do this. JRA. **/ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, @@ -470,7 +474,8 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, goto use_as_is; } -convert: + convert: + if ((destlen*2) < destlen) { /* wrapped ! abort. */ if (!conv_silent) @@ -497,6 +502,9 @@ convert: } i_len = srclen; o_len = destlen; + + again: + retval = smb_iconv(descriptor, (char **)&inbuf, &i_len, &outbuf, &o_len); @@ -521,7 +529,9 @@ convert: /* smb_panic(reason); */ return (size_t)-1; } - + + out: + destlen = destlen - o_len; if (ctx) *dest = (char *)talloc_realloc(ctx,ob,destlen); @@ -536,27 +546,80 @@ convert: return destlen; - use_as_is: + use_as_is: + + /* + * Conversion not supported. This is actually an error, but there are so + * many misconfigured iconv systems and smb.conf's out there we can't just + * fail. Do a very bad conversion instead.... JRA. + */ - /* conversion not supported, use as is */ { - if (srclen && (destlen != srclen)) { - destlen = srclen; - if (ctx) - ob = (char *)talloc_realloc(ctx, ob, destlen); - else - ob = (char *)Realloc(ob, destlen); - if (!ob) { - DEBUG(0, ("convert_string_allocate: realloc failed!\n")); - if (!ctx) - SAFE_FREE(outbuf); - return (size_t)-1; + if (o_len == 0 || i_len == 0) + goto out; + + if (from == CH_UCS2 && to != CH_UCS2) { + /* Can't convert from ucs2 to multibyte. Just truncate this char to ascii. */ + if (i_len < 2) + goto out; + + if (i_len >= 2) { + *outbuf = inbuf[0]; + + outbuf++; + o_len--; + + inbuf += 2; + i_len -= 2; } + + if (o_len == 0 || i_len == 0) + goto out; + + /* Keep trying with the next char... */ + goto again; + + } else if (from != CH_UCS2 && to == CH_UCS2) { + /* Can't convert to ucs2 - just widen by adding zero. */ + if (o_len < 2) + goto out; + + outbuf[0] = inbuf[0]; + outbuf[1] = '\0'; + + inbuf++; + i_len--; + + outbuf += 2; + o_len -= 2; + + if (o_len == 0 || i_len == 0) + goto out; + + /* Keep trying with the next char... */ + goto again; + + } else if (from != CH_UCS2 && to != CH_UCS2) { + /* Failed multibyte to multibyte. Just copy 1 char and + try again. */ + outbuf[0] = inbuf[0]; + + inbuf++; + i_len--; + + outbuf++; + o_len--; + + if (o_len == 0 || i_len == 0) + goto out; + + /* Keep trying with the next char... */ + goto again; + + } else { + /* Keep compiler happy.... */ + goto out; } - if (srclen && ob) - memcpy(ob,(const char *)src,srclen); - *dest = (char *)ob; - return srclen; } } -- cgit From 69b086fdaffe2f10235f85f369453bdf0ab470ed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Feb 2004 20:28:48 +0000 Subject: Fix final valgrind errors with #830. Catch mb conversion error that may not terminate correctly. Jeremy. (This used to be commit a1f7cea9f278ef15206bf48663328c28d295bd6d) --- source3/lib/util_str.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 822ab20628..2d1f596c97 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1293,6 +1293,8 @@ char *strnrchr_m(const char *s, char c, unsigned int n) void strlower_m(char *s) { + size_t len; + /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible @@ -1308,7 +1310,12 @@ void strlower_m(char *s) /* I assume that lowercased string takes the same number of bytes * as source string even in UTF-8 encoding. (VIV) */ - unix_strlower(s,strlen(s)+1,s,strlen(s)+1); + len = strlen(s) + 1; + errno = 0; + unix_strlower(s,len,s,len); + /* Catch mb conversion errors that may not terminate. */ + if (errno) + s[len-1] = '\0'; } /** @@ -1317,6 +1324,8 @@ void strlower_m(char *s) void strupper_m(char *s) { + size_t len; + /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible @@ -1332,7 +1341,12 @@ void strupper_m(char *s) /* I assume that lowercased string takes the same number of bytes * as source string even in multibyte encoding. (VIV) */ - unix_strupper(s,strlen(s)+1,s,strlen(s)+1); + len = strlen(s) + 1; + errno = 0; + unix_strupper(s,len,s,len); + /* Catch mb conversion errors that may not terminate. */ + if (errno) + s[len-1] = '\0'; } /** -- cgit From f97d6e76fb6e4030ca2a56598f9bb81cbd622f8d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 6 Feb 2004 01:14:54 +0000 Subject: Replaced .po with .@PICSUFFIX@ (This used to be commit 9ea39d1c782c2111b086a83bf5f24c8b18fd879e) --- source3/Makefile.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 72b8e33145..1c8341a139 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1096,9 +1096,9 @@ bin/mysql.@SHLIBEXT@: $(MYSQL_OBJ:.o=.@PICSUFFIX@) @$(SHLD) $(LDSHFLAGS) -o $@ $(MYSQL_OBJ:.o=.@PICSUFFIX@) @MYSQL_LIBS@ \ @SONAMEFLAG@`basename $@` -bin/pgsql.@SHLIBEXT@: $(PGSQL_OBJ:.o=.po) +bin/pgsql.@SHLIBEXT@: $(PGSQL_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" - @$(SHLD) $(LDSHFLAGS) -o $@ $(PGSQL_OBJ:.o=.po) @PGSQL_LIBS@ \ + @$(SHLD) $(LDSHFLAGS) -o $@ $(PGSQL_OBJ:.o=.@PICSUFFIX@) @PGSQL_LIBS@ \ @SONAMEFLAG@`basename $@` bin/ldapsam.@SHLIBEXT@: passdb/pdb_ldap.@PICSUFFIX@ @@ -1131,9 +1131,9 @@ bin/CP437.@SHLIBEXT@: $(CP437_OBJ:.o=.@PICSUFFIX@) @$(SHLD) $(LDSHFLAGS) -o $@ $(CP437_OBJ:.o=.@PICSUFFIX@) \ @SONAMEFLAG@`basename $@` -bin/macosxfs.@SHLIBEXT@: $(CHARSET_MACOSXFS_OBJ:.o=.po) +bin/macosxfs.@SHLIBEXT@: $(CHARSET_MACOSXFS_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" - @$(SHLD) $(LDSHFLAGS) -o $@ $(CHARSET_MACOSXFS_OBJ:.o=.po) \ + @$(SHLD) $(LDSHFLAGS) -o $@ $(CHARSET_MACOSXFS_OBJ:.o=.@PICSUFFIX@) \ -framework CoreFoundation @SONAMEFLAG@`basename $@` bin/xml.@SHLIBEXT@: $(XML_OBJ:.o=.@PICSUFFIX@) -- cgit From cfd8958091b84d90e4a823faadcc3fa05a67e4ac Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:42:28 +0000 Subject: (merge from 3.0) I should have done this years ago... This adds the very simple 'admin set password' capability to 'net rpc', much as we have it for 'net ads'. Andrew Bartlett (This used to be commit 5243b89e33efd2ea8842a624d8abd6c5755afb64) --- source3/passdb/pdb_ldap.c | 4 +- source3/utils/net_rpc.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 2 deletions(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index dcb2040530..3db0702c92 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -911,7 +911,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) { if (need_update(sampass, PDB_LMPASSWD)) { - uchar *lm_pw = pdb_get_lanman_passwd(sampass); + const uchar *lm_pw = pdb_get_lanman_passwd(sampass); if (lm_pw) { pdb_sethexpwd(temp, lm_pw, pdb_get_acct_ctrl(sampass)); @@ -925,7 +925,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, } } if (need_update(sampass, PDB_NTPASSWD)) { - uchar *nt_pw = pdb_get_nt_passwd(sampass); + const uchar *nt_pw = pdb_get_nt_passwd(sampass); if (nt_pw) { pdb_sethexpwd(temp, nt_pw, pdb_get_acct_ctrl(sampass)); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 804faf3b9a..eef3adbcb8 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -677,6 +677,135 @@ static int rpc_user_delete(int argc, const char **argv) argc, argv); } +/** + * Set a password for a user on a remote RPC server + * + * All parameters are provided by the run_rpc_command function, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ + +static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid, + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + POLICY_HND connect_pol, domain_pol, user_pol; + SAM_USERINFO_CTR ctr; + SAM_USER_INFO_24 p24; + uchar pwbuf[516]; + const char *user; + const char *new_password; + char *prompt = NULL; + + if (argc < 1) { + d_printf("User must be specified\n"); + rpc_user_usage(argc, argv); + return NT_STATUS_OK; + } + + user = argv[0]; + + if (argv[1]) { + new_password = argv[1]; + } else { + asprintf(&prompt, "Enter new password for %s:", user); + new_password = getpass(prompt); + SAFE_FREE(prompt); + } + + /* Get sam policy and domain handles */ + + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + domain_sid, &domain_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Get handle on user */ + + { + uint32 *user_rids, num_rids, *name_types; + uint32 flags = 0x000003e8; /* Unknown */ + + result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, + flags, 1, &user, + &num_rids, &user_rids, + &name_types); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = cli_samr_open_user(cli, mem_ctx, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + user_rids[0], &user_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + } + + /* Set password on account */ + + ZERO_STRUCT(ctr); + ZERO_STRUCT(p24); + + encode_pw_buffer(pwbuf, new_password, STR_UNICODE); + + init_sam_user_info24(&p24, (char *)pwbuf,24); + + ctr.switch_value = 24; + ctr.info.id24 = &p24; + + result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24, + &cli->user_session_key, &ctr); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Display results */ + + done: + return result; + +} + +/** + * Set a user's password on a remote RPC server + * + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ + +static int rpc_user_password(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_password_internals, + argc, argv); +} + /** * List user's groups on a remote RPC server * @@ -870,6 +999,7 @@ int net_rpc_user(int argc, const char **argv) {"add", rpc_user_add}, {"info", rpc_user_info}, {"delete", rpc_user_delete}, + {"password", rpc_user_password}, {NULL, NULL} }; @@ -2547,6 +2677,7 @@ int net_rpc(int argc, const char **argv) {"oldjoin", net_rpc_oldjoin}, {"testjoin", net_rpc_testjoin}, {"user", net_rpc_user}, + {"password", rpc_user_password}, {"group", net_rpc_group}, {"share", net_rpc_share}, {"file", net_rpc_file}, -- cgit From 57db183e2ec40feb09cfcffb6ead47f78d8d3340 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:46:32 +0000 Subject: (merge from 3.0) Bug found by gd - the new range-reterival code did still had 'member' hardcoded into it. This didn't matter, as we only use it for 'member' so far... Andrew Bartlett (This used to be commit a813d4b6aac655909541966d2d343fe2b55ed188) --- source3/libads/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 79f267a6a8..20a36dfdf5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1655,7 +1655,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, } if (!attr) { ber_free(ptr, 0); - /* nothing here - this feild is just empty */ + /* nothing here - this field is just empty */ *more_strings = False; return NULL; } @@ -1714,7 +1714,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, if (*more_strings) { *next_attribute = talloc_asprintf(mem_ctx, - "member;range=%d-*", + "%s;range=%d-*", + field, *num_strings); if (!*next_attribute) { -- cgit From 72ee7bfd6d2d6219236f4cdcef2570c0eae47f83 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:47:12 +0000 Subject: (merge from 3.0) Make get_dc_list static - we only ask for a sorted list externally. Andrew Bartlett (This used to be commit 5335b9d5eb79dc431fb8e40e61a57370dd09486e) --- source3/libsmb/namequery.c | 47 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index dcbd11048e..8bde6d37ea 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -230,7 +230,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t comparison function used by sort_ip_list */ -int ip_compare(struct in_addr *ip1, struct in_addr *ip2) +static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) { int max_bits1=0, max_bits2=0; int num_interfaces = iface_count(); @@ -292,7 +292,7 @@ static void sort_ip_list(struct in_addr *iplist, int count) qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare); } -void sort_ip_list2(struct ip_service *iplist, int count) +static void sort_ip_list2(struct ip_service *iplist, int count) { if (count <= 1) { return; @@ -1229,32 +1229,12 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) return True; } -/********************************************************************* - small wrapper function to get the DC list and sort it if neccessary -*********************************************************************/ -BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ) -{ - BOOL ordered; - - DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", - (ads_only ? "ads" : lp_name_resolve_order()))); - - if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) - return False; - - /* only sort if we don't already have an ordered list */ - if ( !ordered ) - sort_ip_list2( *ip_list, *count ); - - return True; -} - /******************************************************** Get the IP address list of the domain controllers for a domain. *********************************************************/ -BOOL get_dc_list(const char *domain, struct ip_service **ip_list, +static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only, int *ordered) { fstring resolve_order; @@ -1403,3 +1383,24 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); } + +/********************************************************************* + small wrapper function to get the DC list and sort it if neccessary +*********************************************************************/ +BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ) +{ + BOOL ordered; + + DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", + (ads_only ? "ads" : lp_name_resolve_order()))); + + if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) + return False; + + /* only sort if we don't already have an ordered list */ + if ( !ordered ) + sort_ip_list2( *ip_list, *count ); + + return True; +} + -- cgit From b655b99f7c3e534a18393d562073a6d05488f090 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:47:52 +0000 Subject: (merge from 3.0) Remove unused utility function. Andrew Bartlett (This used to be commit af8248e67bb0f83124dcd250fee5d06a12fe257b) --- source3/libsmb/smbencrypt.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 1d192b816a..c5acedae51 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -226,19 +226,6 @@ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) #endif } -BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) -{ - encode_pw_buffer(data, passwd, (unicode?STR_UNICODE:STR_ASCII)); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("make_oem_passwd_hash\n")); - dump_data(100, data, 516); -#endif - SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); - - return True; -} - /* Does the md5 encryption from the Key Response for NTLMv2. */ void SMBOWFencrypt_ntv2(const uchar kr[16], const DATA_BLOB *srv_chal, -- cgit From 079822437838ff102bc07c0b101038498aaca6c4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:48:28 +0000 Subject: (merge from 3.0) Make this table static const. Andrew Bartlett (This used to be commit 3803cb36e9d94c08bf310c0ef1cdfc29b443dc0e) --- source3/utils/ntlm_auth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 74918045ee..d2a1547f77 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1955,7 +1955,7 @@ static BOOL test_plaintext_lm_only(void) { */ -struct ntlm_tests { +static const struct ntlm_tests { BOOL (*fn)(void); const char *name; } test_table[] = { -- cgit From b38ba022481b05db4762a41dfddace66521fd491 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:49:06 +0000 Subject: (merge from 3.0) Another static function. Andrew Bartlett (This used to be commit 58adb41db19ce528b9267a5ea7f119b9c6893ade) --- source3/lib/smbldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 150450c83d..925bc1fbf0 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -221,7 +221,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { /******************************************************************* find the ldap password ******************************************************************/ -BOOL fetch_ldap_pw(char **dn, char** pw) +static BOOL fetch_ldap_pw(char **dn, char** pw) { char *key = NULL; size_t size; -- cgit From e81074ea20a2f65683d2ef719aaaf8a5c765e8cb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:49:36 +0000 Subject: (merge from 3.0) Remove more unused functions - this time parts of the 'password cache'. Andrew Bartlett (This used to be commit c29c28e4cfc0539eb5e02196dd6cdda7bd433f61) --- source3/libsmb/pwd_cache.c | 45 --------------------------------------------- 1 file changed, 45 deletions(-) diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 7ba6cfc96f..27ca4ddf57 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -80,51 +80,6 @@ void pwd_get_cleartext(struct pwd_info *pwd, fstring clr) } -/**************************************************************************** - Gets lm and nt hashed passwords. -****************************************************************************/ - -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) -{ - if (lm_pwd != NULL) - memcpy(lm_pwd, pwd->smb_lm_pwd, 16); - if (nt_pwd != NULL) - memcpy(nt_pwd, pwd->smb_nt_pwd, 16); -} - -/**************************************************************************** - Makes lm and nt OWF crypts. -****************************************************************************/ - -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) -{ - -#ifdef DEBUG_PASSWORD - DEBUG(100,("client cryptkey: ")); - dump_data(100, (char *)cryptkey, 8); -#endif - - SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_owf_passwd: ")); - dump_data(100, (char *)pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); - DEBUG(100,("nt_sess_pwd: ")); - dump_data(100, (char *)pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); -#endif - - SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("lm_owf_passwd: ")); - dump_data(100, (char *)pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); - DEBUG(100,("lm_sess_pwd: ")); - dump_data(100, (char *)pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); -#endif - - pwd->crypted = True; -} - /**************************************************************************** Gets lm and nt crypts. ****************************************************************************/ -- cgit From 7b6591ee59ed7fe76375bc90fdced33b846c724f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:50:30 +0000 Subject: (merge from 3.0) Remove more unused portions of the 'password cache'. Andrew Bartlett (This used to be commit 33cdb2bd18daca31461bbc45251679f50fd3567f) --- source3/include/smb.h | 13 ------------- source3/libsmb/pwd_cache.c | 42 ++++++------------------------------------ 2 files changed, 6 insertions(+), 49 deletions(-) diff --git a/source3/include/smb.h b/source3/include/smb.h index ea39206f47..7ffbe8f720 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1510,22 +1510,9 @@ struct pwd_info { BOOL null_pwd; BOOL cleartext; - BOOL crypted; fstring password; - uchar smb_lm_pwd[16]; - uchar smb_nt_pwd[16]; - - uchar smb_lm_owf[24]; - uchar smb_nt_owf[128]; - size_t nt_owf_len; - - uchar lm_cli_chal[8]; - uchar nt_cli_chal[128]; - size_t nt_cli_chal_len; - - uchar sess_key[16]; }; typedef struct user_struct diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 27ca4ddf57..e010f226a0 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -27,43 +27,24 @@ static void pwd_init(struct pwd_info *pwd) { memset((char *)pwd->password , '\0', sizeof(pwd->password )); - memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd)); - memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd)); - memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf)); - memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf)); pwd->null_pwd = True; /* safest option... */ - pwd->cleartext = False; - pwd->crypted = False; } /**************************************************************************** - Makes lm and nt hashed passwords. + Stores a cleartext password. ****************************************************************************/ -static void pwd_make_lm_nt_16(struct pwd_info *pwd, const char *clr) +void pwd_set_cleartext(struct pwd_info *pwd, const char *clr) { pwd_init(pwd); - - if (!clr) { - ZERO_STRUCT(pwd->smb_nt_pwd); - ZERO_STRUCT(pwd->smb_lm_pwd); - pwd->null_pwd = True; + if (clr) { + fstrcpy(pwd->password, clr); + pwd->null_pwd = False; } else { - nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); - pwd->null_pwd = False; + pwd->null_pwd = True; } - pwd->crypted = False; -} - -/**************************************************************************** - Stores a cleartext password. -****************************************************************************/ -void pwd_set_cleartext(struct pwd_info *pwd, const char *clr) -{ - pwd_make_lm_nt_16(pwd, clr); - fstrcpy(pwd->password, clr); pwd->cleartext = True; } @@ -80,14 +61,3 @@ void pwd_get_cleartext(struct pwd_info *pwd, fstring clr) } -/**************************************************************************** - Gets lm and nt crypts. -****************************************************************************/ - -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) -{ - if (lm_owf != NULL) - memcpy(lm_owf, pwd->smb_lm_owf, 24); - if (nt_owf != NULL) - memcpy(nt_owf, pwd->smb_nt_owf, 24); -} -- cgit From f7c1c68e19c00c3b107d4fd08401ed8aeb09bbaa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:51:11 +0000 Subject: (merge from 3.0) Samba hasn't used this function for ages - it's now handled deep in the auth subsystem. Andrew Bartlett (This used to be commit bb505ca696427f105d05a0b9aab6d5eee043ede6) --- source3/smbd/uid.c | 69 ------------------------------------------------------ 1 file changed, 69 deletions(-) diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 7979ffe854..09cf899522 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -369,72 +369,3 @@ BOOL unbecome_user(void) return True; } -/***************************************************************** - Convert the supplementary 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++) { - gid_t new_grp; - - if (NT_STATUS_IS_OK(sid_to_gid(&ptok->user_sids[i], &new_grp))) { - /* - * 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; -} - - -- cgit From 9b586b5a645c27d48d3cf8eb788e297ba83114d6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 11:59:55 +0000 Subject: (merge from 3.0) Make more functions static, and remove duplication in the use of functions in lib/smbpasswd.c that were exact duplicates of functions in passdb/passdb.c (These should perhaps be pulled back out to smbpasswd.c, but that can occour later). This also includes some >14 character password changes, and the start of a move away from using 'admin user' to determine if the user is root (as root can login without setting 'admin user'). Andrew Bartlett (This used to be commit be0704abb919152c359a735023283acbf9be3076) --- source3/Makefile.in | 2 +- source3/lib/iconv.c | 2 +- source3/lib/smbpasswd.c | 200 ---------------------------------------- source3/nsswitch/winbindd_rpc.c | 2 +- source3/passdb/pdb_get_set.c | 17 +++- source3/rpc_parse/parse_misc.c | 2 +- source3/smbd/nttrans.c | 5 +- source3/smbd/server.c | 2 +- source3/utils/net_rpc_join.c | 2 +- source3/utils/net_rpc_samsync.c | 12 +-- source3/web/cgi.c | 2 +- 11 files changed, 30 insertions(+), 218 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 1c8341a139..7fa0c14bd0 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -180,7 +180,7 @@ LIB_OBJ = lib/version.o lib/charcnv.o lib/debug.o lib/fault.o \ lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \ lib/ms_fnmatch.o lib/select.o lib/messages.o \ lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \ - lib/md5.o lib/hmacmd5.o lib/iconv.o lib/smbpasswd.o \ + lib/md5.o lib/hmacmd5.o lib/iconv.o \ nsswitch/wb_client.o nsswitch/wb_common.o \ lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \ lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \ diff --git a/source3/lib/iconv.c b/source3/lib/iconv.c index d0d2dcd1c4..7df73192f2 100644 --- a/source3/lib/iconv.c +++ b/source3/lib/iconv.c @@ -105,7 +105,7 @@ NTSTATUS smb_register_charset(struct charset_functions *funcs) return NT_STATUS_OK; } -void lazy_initialize_iconv(void) +static void lazy_initialize_iconv(void) { static BOOL initialized; int i; diff --git a/source3/lib/smbpasswd.c b/source3/lib/smbpasswd.c index 92ae1ffea2..e69de29bb2 100644 --- a/source3/lib/smbpasswd.c +++ b/source3/lib/smbpasswd.c @@ -1,200 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - smbpasswd file format routines - - Copyright (C) Andrew Tridgell 1992-1998 - Modified by Jeremy Allison 1995. - Modified by Gerald (Jerry) Carter 2000-2001 - Copyright (C) Tim Potter 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/*! \file lib/smbpasswd.c - - The smbpasswd file is used to store encrypted passwords in a similar - fashion to the /etc/passwd file. The format is colon separated fields - with one user per line like so: - - ::::: - - The username and uid must correspond to an entry in the /etc/passwd - file. The lanman and nt password hashes are 32 hex digits corresponding - to the 16-byte lanman and nt hashes respectively. - - The password last change time is stored as a string of the format - LCD- where the change time is expressed as an - - 'N' No password - 'D' Disabled - 'H' Homedir required - 'T' Temp account. - 'U' User account (normal) - 'M' MNS logon user account - what is this ? - 'W' Workstation account - 'S' Server account - 'L' Locked account - 'X' No Xpiry on password - 'I' Interdomain trust account - -*/ - -#include "includes.h" - -/*! Convert 32 hex characters into a 16 byte array. */ - -BOOL smbpasswd_gethexpwd(char *p, unsigned char *pwd) -{ - int i; - unsigned char lonybble, hinybble; - const char *hexchars = "0123456789ABCDEF"; - char *p1, *p2; - - if (!p) return (False); - - for (i = 0; i < 32; i += 2) - { - hinybble = toupper(p[i]); - lonybble = toupper(p[i + 1]); - - p1 = strchr_m(hexchars, hinybble); - p2 = strchr_m(hexchars, lonybble); - - if (!p1 || !p2) - { - return (False); - } - - hinybble = PTR_DIFF(p1, hexchars); - lonybble = PTR_DIFF(p2, hexchars); - - pwd[i / 2] = (hinybble << 4) | lonybble; - } - return (True); -} - -/*! Convert a 16-byte array into 32 hex characters. */ - -void smbpasswd_sethexpwd(fstring p, unsigned char *pwd, uint16 acb_info) -{ - if (pwd != NULL) { - int i; - for (i = 0; i < 16; i++) - slprintf(&p[i*2], 3, "%02X", pwd[i]); - } else { - if (acb_info & ACB_PWNOTREQ) - safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33); - else - safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33); - } -} - -/*! Decode the account control bits (ACB) info from a string. */ - -uint16 smbpasswd_decode_acb_info(const char *p) -{ - uint16 acb_info = 0; - BOOL finished = False; - - /* - * Check if the account type bits have been encoded after the - * NT password (in the form [NDHTUWSLXI]). - */ - - if (*p != '[') return 0; - - for (p++; *p && !finished; p++) - { - switch (*p) { - case 'N': /* 'N'o password. */ - acb_info |= ACB_PWNOTREQ; - break; - case 'D': /* 'D'isabled. */ - acb_info |= ACB_DISABLED; - break; - case 'H': /* 'H'omedir required. */ - acb_info |= ACB_HOMDIRREQ; - break; - case 'T': /* 'T'emp account. */ - acb_info |= ACB_TEMPDUP; - break; - case 'U': /* 'U'ser account (normal). */ - acb_info |= ACB_NORMAL; - break; - case 'M': /* 'M'NS logon user account. What is this ? */ - acb_info |= ACB_MNS; - break; - case 'W': /* 'W'orkstation account. */ - acb_info |= ACB_WSTRUST; - break; - case 'S': /* 'S'erver account. */ - acb_info |= ACB_SVRTRUST; - break; - case 'L': /* 'L'ocked account. */ - acb_info |= ACB_AUTOLOCK; - break; - case 'X': /* No 'X'piry on password */ - acb_info |= ACB_PWNOEXP; - break; - case 'I': /* 'I'nterdomain trust account. */ - acb_info |= ACB_DOMTRUST; - break; - - case ' ': - break; - case ':': - case '\n': - case '\0': - case ']': - default: - finished = True; - break; - } - } - - return acb_info; -} - -/*! Encode account control bits (ACBs) into a string. */ - -char *smbpasswd_encode_acb_info(uint16 acb_info) -{ - static fstring acct_str; - size_t i = 0; - - acct_str[i++] = '['; - - if (acb_info & ACB_PWNOTREQ ) acct_str[i++] = 'N'; - if (acb_info & ACB_DISABLED ) acct_str[i++] = 'D'; - if (acb_info & ACB_HOMDIRREQ) acct_str[i++] = 'H'; - if (acb_info & ACB_TEMPDUP ) acct_str[i++] = 'T'; - if (acb_info & ACB_NORMAL ) acct_str[i++] = 'U'; - if (acb_info & ACB_MNS ) acct_str[i++] = 'M'; - if (acb_info & ACB_WSTRUST ) acct_str[i++] = 'W'; - if (acb_info & ACB_SVRTRUST ) acct_str[i++] = 'S'; - if (acb_info & ACB_AUTOLOCK ) acct_str[i++] = 'L'; - if (acb_info & ACB_PWNOEXP ) acct_str[i++] = 'X'; - if (acb_info & ACB_DOMTRUST ) acct_str[i++] = 'I'; - - for ( ; i < NEW_PW_FORMAT_SPACE_PADDED_LEN - 2 ; i++ ) - acct_str[i] = ' '; - - i = NEW_PW_FORMAT_SPACE_PADDED_LEN - 2; - acct_str[i++] = ']'; - acct_str[i++] = '\0'; - - return acct_str; -} diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 21e0c3092e..d4428a2f59 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -792,7 +792,7 @@ static int get_ldap_seq(const char *server, int port, uint32 *seq) LDAP queries **********************************************************************/ -int get_ldap_sequence_number( const char* domain, uint32 *seq) +static int get_ldap_sequence_number( const char* domain, uint32 *seq) { int ret = -1; int i, port = LDAP_PORT; diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 869165f1dc..be03157636 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -1102,13 +1102,24 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext) if (!sampass || !plaintext) return False; - nt_lm_owf_gen (plaintext, new_nt_p16, new_lanman_p16); + /* Calculate the MD4 hash (NT compatible) of the password */ + E_md4hash(plaintext, new_nt_p16); if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED)) return False; - if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED)) - return False; + if (!E_deshash(plaintext, new_lanman_p16)) { + /* E_deshash returns false for 'long' passwords (> 14 + DOS chars). This allows us to match Win2k, which + does not store a LM hash for these passwords (which + would reduce the effective password length to 14 */ + + if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED)) + return False; + } else { + if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED)) + return False; + } if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED)) return False; diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index b34efa6667..cea31c88a8 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -32,7 +32,7 @@ static TALLOC_CTX *current_rpc_talloc = NULL; -TALLOC_CTX *get_current_rpc_talloc(void) +static TALLOC_CTX *get_current_rpc_talloc(void) { return current_rpc_talloc; } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 25721d99a8..0a2843629e 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -56,7 +56,7 @@ struct generic_mapping file_generic_mapping = { FILE_GENERIC_ALL }; -char *nttrans_realloc(char **ptr, size_t size) +static char *nttrans_realloc(char **ptr, size_t size) { char *tptr = NULL; if (ptr==NULL) @@ -2022,11 +2022,12 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, SMB_NTQUOTA_STRUCT qt; SMB_NTQUOTA_LIST *tmp_list; SMB_NTQUOTA_HANDLE *qt_handle = NULL; + extern struct current_user current_user; ZERO_STRUCT(qt); /* access check */ - if (conn->admin_user != True) { + if (current_user.uid != 0) { DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n", lp_servicename(SNUM(conn)),conn->user)); return ERROR_DOS(ERRDOS,ERRnoaccess); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index e7aa41e343..26e4021443 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -145,7 +145,7 @@ static void msg_exit_server(int msg_type, pid_t src, void *buf, size_t len) Have we reached the process limit ? ****************************************************************************/ -BOOL allowable_number_of_smbd_processes(void) +static BOOL allowable_number_of_smbd_processes(void) { int max_processes = lp_max_smbd_processes(); diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index 6bfeedc8a0..52e295949e 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -42,7 +42,7 @@ * @return A shell status integer (0 for success) * **/ -int net_rpc_join_ok(const char *domain) +static int net_rpc_join_ok(const char *domain) { struct cli_state *cli; uchar stored_md4_trust_password[16]; diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index e97a362acc..cb395de828 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -62,21 +62,21 @@ static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a) if (memcmp(a->pass.buf_lm_pwd, zero_buf, 16) != 0) { sam_pwd_hash(a->user_rid, a->pass.buf_lm_pwd, lm_passwd, 0); - smbpasswd_sethexpwd(hex_lm_passwd, lm_passwd, a->acb_info); + pdb_sethexpwd(hex_lm_passwd, lm_passwd, a->acb_info); } else { - smbpasswd_sethexpwd(hex_lm_passwd, NULL, 0); + pdb_sethexpwd(hex_lm_passwd, NULL, 0); } if (memcmp(a->pass.buf_nt_pwd, zero_buf, 16) != 0) { sam_pwd_hash(a->user_rid, a->pass.buf_nt_pwd, nt_passwd, 0); - smbpasswd_sethexpwd(hex_nt_passwd, nt_passwd, a->acb_info); + pdb_sethexpwd(hex_nt_passwd, nt_passwd, a->acb_info); } else { - smbpasswd_sethexpwd(hex_nt_passwd, NULL, 0); + pdb_sethexpwd(hex_nt_passwd, NULL, 0); } printf("%s:%d:%s:%s:%s:LCT-0\n", unistr2_static(&a->uni_acct_name), a->user_rid, hex_lm_passwd, hex_nt_passwd, - smbpasswd_encode_acb_info(a->acb_info)); + pdb_encode_acct_ctrl(a->acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN)); } static void display_domain_info(SAM_DOMAIN_INFO *a) @@ -432,7 +432,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) pstrcpy(add_script, lp_addmachine_script()); } else { DEBUG(1, ("Unknown user type: %s\n", - smbpasswd_encode_acb_info(delta->acb_info))); + pdb_encode_acct_ctrl(delta->acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN))); nt_ret = NT_STATUS_UNSUCCESSFUL; goto done; } diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 8a103fa57f..aac009893c 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -91,7 +91,7 @@ static char *grab_line(FILE *f, int *cl) (This was in rfc1738_unescape(), but that broke the squid helper) **/ -void plus_to_space_unescape(char *buf) +static void plus_to_space_unescape(char *buf) { char *p=buf; -- cgit From 41de88438b6217b4066ef78a623dd6244f5959d8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 12:00:40 +0000 Subject: (merge from 3.0) Add some help for 'net rpc password'. Andrew Bartlett (This used to be commit 2c6f1966d6c25238d73a46132c05794677c3a882) --- source3/utils/net_rpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index eef3adbcb8..dddfec2255 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -2610,6 +2610,7 @@ int net_rpc_usage(int argc, const char **argv) d_printf(" net rpc oldjoin \t\t\tto join a domain created in server manager\n\n\n"); d_printf(" net rpc testjoin \t\ttests that a join is valid\n"); d_printf(" net rpc user \t\t\tto add, delete and list users\n"); + d_printf(" net rpc password [] -Uadmin_username%%admin_pass"); d_printf(" net rpc group \t\tto list groups\n"); d_printf(" net rpc share \t\tto add, delete, and list shares\n"); d_printf(" net rpc file \t\t\tto list open files\n"); -- cgit From e0c480f77f35e096e241217ad677b21eaceec4bd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 12:01:43 +0000 Subject: (merge from 3.0) Make it possible to 'net rpc samdump' of any domain you are currently joined to, despite any smb.conf settings. Work to allow the same for 'net rpc vampire', but instead give a clear error message on what is incorrect. Andrew Bartlett (This used to be commit c4b6bd85978b61c4c9c34dde122e968c3771f2e6) --- source3/utils/net.h | 2 + source3/utils/net_rpc.c | 113 +++++++++++++++++++++++++++------------- source3/utils/net_rpc_samsync.c | 90 ++++++++++++++------------------ 3 files changed, 116 insertions(+), 89 deletions(-) diff --git a/source3/utils/net.h b/source3/utils/net.h index 78c0aad86a..94e6de9d18 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -35,6 +35,8 @@ /* We want an anonymous connection */ #define NET_FLAGS_ANONYMOUS 16 +/* don't open an RPC pipe */ +#define NET_FLAGS_NO_PIPE 32 extern int opt_maxusers; extern const char *opt_comment; diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index dddfec2255..c7e014131b 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -37,7 +37,8 @@ /* A function of this type is passed to the 'run_rpc_command' wrapper */ -typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_CTX *, int, const char **); +typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, const char *, + struct cli_state *, TALLOC_CTX *, int, const char **); /** * Many of the RPC functions need the domain sid. This function gets @@ -48,13 +49,12 @@ typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_C * @return The Domain SID of the remote machine. **/ -static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx) +static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx, char **domain_name) { DOM_SID *domain_sid; POLICY_HND pol; NTSTATUS result = NT_STATUS_OK; uint32 info_class = 5; - char *domain_name; if (!cli_nt_session_open (cli, PI_LSARPC)) { fprintf(stderr, "could not initialise lsa pipe\n"); @@ -69,7 +69,7 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem } result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, - &domain_name, &domain_sid); + domain_name, &domain_sid); if (!NT_STATUS_IS_OK(result)) { error: fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain); @@ -107,6 +107,7 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co TALLOC_CTX *mem_ctx; NTSTATUS nt_status; DOM_SID *domain_sid; + char *domain_name; /* make use of cli_state handed over as an argument, if possible */ if (!cli_arg) @@ -126,13 +127,15 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co return -1; } - domain_sid = net_get_remote_domain_sid(cli, mem_ctx); + domain_sid = net_get_remote_domain_sid(cli, mem_ctx, &domain_name); - if (!cli_nt_session_open(cli, pipe_idx)) { - DEBUG(0, ("Could not initialise pipe\n")); + if (!(conn_flags & NET_FLAGS_NO_PIPE)) { + if (!cli_nt_session_open(cli, pipe_idx)) { + DEBUG(0, ("Could not initialise pipe\n")); + } } - nt_status = fn(domain_sid, cli, mem_ctx, argc, argv); + nt_status = fn(domain_sid, domain_name, cli, mem_ctx, argc, argv); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status))); @@ -140,10 +143,11 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co DEBUG(5, ("rpc command function succedded\n")); } - - if (cli->nt_pipe_fnum) - cli_nt_session_close(cli); - + if (!(conn_flags & NET_FLAGS_NO_PIPE)) { + if (cli->nt_pipe_fnum) + cli_nt_session_close(cli); + } + /* close the connection only if it was opened here */ if (!cli_arg) cli_shutdown(cli); @@ -173,8 +177,9 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co * @return Normal NTSTATUS return. **/ -static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, - int argc, const char **argv) { +static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) { return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup); } @@ -191,7 +196,8 @@ static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cl int net_rpc_changetrustpw(int argc, const char **argv) { - return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals, + return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, + rpc_changetrustpw_internals, argc, argv); } @@ -219,9 +225,10 @@ int net_rpc_changetrustpw(int argc, const char **argv) * @return Normal NTSTATUS return. **/ -static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, struct cli_state *cli, - TALLOC_CTX *mem_ctx, - int argc, const char **argv) { +static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + int argc, const char **argv) { fstring trust_passwd; unsigned char orig_trust_passwd_hash[16]; @@ -367,7 +374,8 @@ int net_rpc_join(int argc, const char **argv) **/ static NTSTATUS -rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli, +rpc_info_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { POLICY_HND connect_pol, domain_pol; @@ -442,16 +450,17 @@ int net_rpc_info(int argc, const char **argv) **/ static NTSTATUS -rpc_getsid_internals(const DOM_SID *domain_sid, struct cli_state *cli, - TALLOC_CTX *mem_ctx, int argc, const char **argv) +rpc_getsid_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) { fstring sid_str; sid_to_string(sid_str, domain_sid); d_printf("Storing SID %s for Domain %s in secrets.tdb\n", - sid_str, lp_workgroup()); + sid_str, domain_name); - if (!secrets_store_domain_sid(global_myname(), domain_sid)) { + if (!secrets_store_domain_sid(domain_name, domain_sid)) { DEBUG(0,("Can't store domain SID\n")); return NT_STATUS_UNSUCCESSFUL; } @@ -504,7 +513,8 @@ static int rpc_user_usage(int argc, const char **argv) * @return Normal NTSTATUS return. **/ -static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, +static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { POLICY_HND connect_pol, domain_pol, user_pol; @@ -593,6 +603,7 @@ static int rpc_user_add(int argc, const char **argv) **/ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid, + const char *domain_name, struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -694,6 +705,7 @@ static int rpc_user_delete(int argc, const char **argv) **/ static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid, + const char *domain_name, struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -823,7 +835,8 @@ static int rpc_user_password(int argc, const char **argv) **/ static NTSTATUS -rpc_user_info_internals(const DOM_SID *domain_sid, struct cli_state *cli, +rpc_user_info_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { POLICY_HND connect_pol, domain_pol, user_pol; @@ -925,7 +938,8 @@ static int rpc_user_info(int argc, const char **argv) **/ static NTSTATUS -rpc_user_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, +rpc_user_list_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { POLICY_HND connect_pol, domain_pol; @@ -1047,7 +1061,8 @@ static int rpc_group_usage(int argc, const char **argv) **/ static NTSTATUS -rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, +rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { POLICY_HND connect_pol, domain_pol; @@ -1237,7 +1252,8 @@ static int rpc_group_list(int argc, const char **argv) } static NTSTATUS -rpc_group_members_internals(const DOM_SID *domain_sid, struct cli_state *cli, +rpc_group_members_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS result; @@ -1387,7 +1403,8 @@ static int rpc_share_usage(int argc, const char **argv) * @return Normal NTSTATUS return. **/ static NTSTATUS -rpc_share_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, +rpc_share_add_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx,int argc, const char **argv) { WERROR result; @@ -1435,7 +1452,8 @@ static int rpc_share_add(int argc, const char **argv) * @return Normal NTSTATUS return. **/ static NTSTATUS -rpc_share_del_internals(const DOM_SID *domain_sid, struct cli_state *cli, +rpc_share_del_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx,int argc, const char **argv) { WERROR result; @@ -1504,7 +1522,8 @@ static void display_share_info_1(SRV_SHARE_INFO_1 *info1) **/ static NTSTATUS -rpc_share_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, +rpc_share_list_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { SRV_SHARE_INFO_CTR ctr; @@ -1580,7 +1599,8 @@ static int rpc_file_usage(int argc, const char **argv) * @return Normal NTSTATUS return. **/ static NTSTATUS -rpc_file_close_internals(const DOM_SID *domain_sid, struct cli_state *cli, +rpc_file_close_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { WERROR result; @@ -1644,7 +1664,8 @@ static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3) **/ static NTSTATUS -rpc_file_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, +rpc_file_list_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { SRV_FILE_INFO_CTR ctr; @@ -1748,6 +1769,7 @@ int net_rpc_file(int argc, const char **argv) **/ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, + const char *domain_name, struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -1782,6 +1804,7 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, **/ static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid, + const char *domain_name, struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -1840,7 +1863,9 @@ static int rpc_shutdown_abort(int argc, const char **argv) * @return Normal NTSTATUS return. **/ -static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, +static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; @@ -1925,7 +1950,9 @@ static int rpc_shutdown(int argc, const char **argv) * @return normal NTSTATUS return code */ -static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, +static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { POLICY_HND connect_pol, domain_pol, user_pol; @@ -2280,8 +2307,10 @@ static int rpc_trustdom_usage(int argc, const char **argv) } -static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, - int argc, const char **argv) +static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) { fstring str_sid; sid_to_string(str_sid, domain_sid); @@ -2592,7 +2621,17 @@ BOOL net_rpc_check(unsigned flags) return ret; } +/* dump sam database via samsync rpc calls */ +static int rpc_samdump(int argc, const char **argv) { + return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals, + argc, argv); +} +/* syncronise sam database via samsync rpc calls */ +static int rpc_vampire(int argc, const char **argv) { + return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals, + argc, argv); +} /****************************************************************************/ diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index cb395de828..882f3a02bc 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -196,36 +196,29 @@ static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret } /* dump sam database via samsync rpc calls */ -int rpc_samdump(int argc, const char **argv) +NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) { - struct cli_state *cli = NULL; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uchar trust_password[16]; DOM_CRED ret_creds; uint32 sec_channel; ZERO_STRUCT(ret_creds); - /* Connect to remote machine */ - if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) { - return 1; - } - - fstrcpy(cli->domain, lp_workgroup()); - - if (!cli_nt_session_open(cli, PI_NETLOGON)) { - DEBUG(0,("Could not open connection to NETLOGON pipe\n")); - goto fail; - } + fstrcpy(cli->domain, domain_name); - if (!secrets_fetch_trust_account_password(lp_workgroup(), + if (!secrets_fetch_trust_account_password(domain_name, trust_password, NULL, &sec_channel)) { DEBUG(0,("Could not fetch trust account password\n")); goto fail; } - if (!NT_STATUS_IS_OK(cli_nt_establish_netlogon(cli, sec_channel, - trust_password))) { + if (!NT_STATUS_IS_OK(nt_status = cli_nt_establish_netlogon(cli, sec_channel, + trust_password))) { DEBUG(0,("Error connecting to NETLOGON pipe\n")); goto fail; } @@ -234,15 +227,11 @@ int rpc_samdump(int argc, const char **argv) dump_database(cli, SAM_DATABASE_BUILTIN, &ret_creds); dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); - cli_nt_session_close(cli); - - return 0; + nt_status = NT_STATUS_OK; fail: - if (cli) { - cli_nt_session_close(cli); - } - return -1; + cli_nt_session_close(cli); + return nt_status; } /* Convert a SAM_ACCOUNT_DELTA to a SAM_ACCOUNT. */ @@ -457,7 +446,6 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) nt_ret = NT_STATUS_NO_SUCH_USER; goto done; } - } sid_copy(&user_sid, get_global_sam_sid()); @@ -1020,75 +1008,73 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds, } /* dump sam database via samsync rpc calls */ -int rpc_vampire(int argc, const char **argv) +NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) { NTSTATUS result; - struct cli_state *cli = NULL; uchar trust_password[16]; DOM_CRED ret_creds; - DOM_SID dom_sid; + fstring my_dom_sid_str; + fstring rem_dom_sid_str; uint32 sec_channel; ZERO_STRUCT(ret_creds); - /* Connect to remote machine */ - if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | - NET_FLAGS_PDC))) { - return 1; + if (!sid_equal(domain_sid, get_global_sam_sid())) { + d_printf("Cannot import users from %s at this time, " + "as the current domain:\n\t%s: %s\nconflicts " + "with the remote domain\n\t%s: %s\n" + "Perhaps you need to set: \n\n\tsecurity=user\n\tworkgroup=%s\n\n in your smb.conf?\n", + domain_name, + get_global_sam_name(), sid_to_string(my_dom_sid_str, + get_global_sam_sid()), + domain_name, sid_to_string(rem_dom_sid_str, domain_sid), + domain_name); + return NT_STATUS_UNSUCCESSFUL; } - if (!cli_nt_session_open(cli, PI_NETLOGON)) { - DEBUG(0,("Error connecting to NETLOGON pipe\n")); - goto fail; - } + fstrcpy(cli->domain, domain_name); - if (!secrets_fetch_trust_account_password(opt_target_workgroup, + if (!secrets_fetch_trust_account_password(domain_name, trust_password, NULL, &sec_channel)) { + result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; d_printf("Could not retrieve domain trust secret\n"); goto fail; } - result = cli_nt_establish_netlogon(cli, sec_channel, trust_password); + result = cli_nt_establish_netlogon(cli, sec_channel, trust_password); if (!NT_STATUS_IS_OK(result)) { d_printf("Failed to setup BDC creds\n"); goto fail; } - sid_copy( &dom_sid, get_global_sam_sid() ); - result = fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds, dom_sid); + result = fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds, *domain_sid); if (!NT_STATUS_IS_OK(result)) { d_printf("Failed to fetch domain database: %s\n", nt_errstr(result)); if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) d_printf("Perhaps %s is a Windows 2000 native mode " - "domain?\n", opt_target_workgroup); + "domain?\n", domain_name); goto fail; } - sid_copy(&dom_sid, &global_sid_Builtin); - result = fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds, - dom_sid); + global_sid_Builtin); if (!NT_STATUS_IS_OK(result)) { d_printf("Failed to fetch builtin database: %s\n", nt_errstr(result)); goto fail; - } + } /* Currently we crash on PRIVS somewhere in unmarshalling */ /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */ - cli_nt_session_close(cli); - - return 0; - fail: - if (cli) - cli_nt_session_close(cli); - - return -1; + return result; } -- cgit From bbfd3a90ca9f34bf777fde0e9aeb434c058d205a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 12:02:28 +0000 Subject: (merge from 3.0) More 'static' work. Andrew Bartlett (This used to be commit 620f909eed3d994d01ca53068a33856d25917144) --- source3/lib/util_sock.c | 2 +- source3/smbd/server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 328ca92727..12c748e5f2 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -954,7 +954,7 @@ char *get_peer_addr(int fd) return addr_buf; } -char *get_socket_addr(int fd) +static char *get_socket_addr(int fd) { struct sockaddr sa; struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 26e4021443..e2ffe8cc9f 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -22,7 +22,7 @@ #include "includes.h" -int am_parent = 1; +static int am_parent = 1; /* the last message the was processed */ int last_message = -1; -- cgit From 880f3b2952592133fb8da640aab73449e13f2ff6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 12:03:14 +0000 Subject: (merge from 3.0) Add static, and assert that we will never overflow the static fstring in pdb_encode_acct_ctrl() (All current callers are fine) Andrew Bartlett (This used to be commit badf7f64fb38dfd40bdf65b19e9dd8932d5e6c3b) --- source3/passdb/passdb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 52dee801ad..d45450a4fd 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -412,7 +412,7 @@ NTSTATUS pdb_free_sam(SAM_ACCOUNT **user) * SSS ***************************************************************************/ -NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd) +static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd) { const char *guest_account = lp_guestaccount(); GROUP_MAP map; @@ -475,6 +475,9 @@ NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd) char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length) { static fstring acct_str; + + SMB_ASSERT(length <= sizeof(acct_str)); + size_t i = 0; acct_str[i++] = '['; -- cgit From 37ef59d4c323a068b978b6beecef367f736b4a86 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 12:04:23 +0000 Subject: (merge from 3.0) When we set a domain sid, force get_global_sam_sid() to do it's work again. This should ensure that the value it returns is always consistant. Andrew Bartlett (This used to be commit fb13c61d4eee943e44632a0d1ba57b19602d67a4) --- source3/Makefile.in | 4 ++-- source3/passdb/machine_sid.c | 7 +++++++ source3/passdb/secrets.c | 8 +++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 7fa0c14bd0..77ae8a0bdd 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -211,7 +211,7 @@ LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \ LIBADS_SERVER_OBJ = libads/util.o libads/kerberos_verify.o -SECRETS_OBJ = passdb/secrets.o +SECRETS_OBJ = passdb/secrets.o passdb/machine_sid.o LIBNMB_OBJ = libsmb/unexpected.o libsmb/namecache.o libsmb/nmblib.o \ libsmb/namequery.o libsmb/conncache.o @@ -293,7 +293,7 @@ GUMS_OBJ = sam/gums.o sam/gums_api.o sam/gums_helper.o @GUMS_STATIC@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ - passdb/machine_sid.o passdb/util_sam_sid.o passdb/pdb_compat.o \ + passdb/util_sam_sid.o passdb/pdb_compat.o \ passdb/privileges.o passdb/lookup_sid.o @PDB_STATIC@ passdb/pdb_sql.o XML_OBJ = passdb/pdb_xml.o diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c index 4e7476781c..1fb3569f76 100644 --- a/source3/passdb/machine_sid.c +++ b/source3/passdb/machine_sid.c @@ -198,3 +198,10 @@ DOM_SID *get_global_sam_sid(void) return global_sam_sid; } +/** + * Force get_global_sam_sid to requery the backends + */ +void reset_global_sam_sid() +{ + SAFE_FREE(global_sam_sid); +} diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 7317a4cf06..7531435e84 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -99,10 +99,16 @@ BOOL secrets_delete(const char *key) BOOL secrets_store_domain_sid(const char *domain, const DOM_SID *sid) { fstring key; + BOOL ret; slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain); strupper_m(key); - return secrets_store(key, sid, sizeof(DOM_SID)); + ret = secrets_store(key, sid, sizeof(DOM_SID)); + + /* Force a re-query, in case we modified our domain */ + if (ret) + reset_global_sam_sid(); + return ret; } BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid) -- cgit From 119cbcde624629f86e552dff91825bc4a3c92052 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 12:06:05 +0000 Subject: (merge from 3.0) nsswitch/winbindd_util.c: add static smbd/uid.c: remove unused function Andrew Bartlett (This used to be commit 4822a3f73610f6e468c447f1282246f13a378cde) --- source3/nsswitch/winbindd_util.c | 2 +- source3/smbd/uid.c | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 076ab1a2fc..eecb36a30f 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -200,7 +200,7 @@ void rescan_trusted_domains( void ) rescan our domains looking for new trusted domains ********************************************************************/ -void add_trusted_domains( struct winbindd_domain *domain ) +static void add_trusted_domains( struct winbindd_domain *domain ) { TALLOC_CTX *mem_ctx; NTSTATUS result; diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 09cf899522..f3d9004dd9 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -310,17 +310,6 @@ static void pop_conn_ctx(void) ctx_p->vuid = UID_FIELD_INVALID; } -void init_conn_ctx(void) -{ - int i; - - /* Initialise connection context stack */ - for (i = 0; i < MAX_SEC_CTX_DEPTH; i++) { - conn_ctx_stack[i].conn = NULL; - conn_ctx_stack[i].vuid = UID_FIELD_INVALID; - } -} - /**************************************************************************** Temporarily become a root user. Must match with unbecome_root(). Saves and restores the connection context. -- cgit From 1b8ad0569da2c0569c2bdff0c1e0f2b7a96d3112 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 12:06:48 +0000 Subject: (merge from 3.0) Add more static... Andrew Bartlett (This used to be commit 6391e2cc8e5b224c002b57ce615b9b8052eeb346) --- source3/nsswitch/winbindd_acct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/nsswitch/winbindd_acct.c b/source3/nsswitch/winbindd_acct.c index 08b9e2172c..0d96756fdb 100644 --- a/source3/nsswitch/winbindd_acct.c +++ b/source3/nsswitch/winbindd_acct.c @@ -436,7 +436,7 @@ WINBINDD_PW* wb_getpwuid( const uid_t uid ) /********************************************************************** **********************************************************************/ -BOOL wb_storepwnam( const WINBINDD_PW *pw ) +static BOOL wb_storepwnam( const WINBINDD_PW *pw ) { char *namekey, *uidkey; TDB_DATA data; @@ -566,7 +566,7 @@ WINBINDD_GR* wb_getgrgid( gid_t gid ) /********************************************************************** **********************************************************************/ -BOOL wb_storegrnam( const WINBINDD_GR *grp ) +static BOOL wb_storegrnam( const WINBINDD_GR *grp ) { char *namekey, *gidkey; TDB_DATA data; -- cgit From c49ebaa777a1b22b9e5d6efe399f9f9206683cba Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 12:09:17 +0000 Subject: Actually remove this (now empty) file from the repository. Andrew Bartlett (This used to be commit 19da2b936a716dc26d361db82280e73e81d683da) --- source3/lib/smbpasswd.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 source3/lib/smbpasswd.c diff --git a/source3/lib/smbpasswd.c b/source3/lib/smbpasswd.c deleted file mode 100644 index e69de29bb2..0000000000 -- cgit From 4a72e82d6940dd717199819e68d9ef28570053ed Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 9 Feb 2004 00:59:34 +0000 Subject: Apply James' printf format checking patch for SGI MIPSPro compiler. (This used to be commit b354fa606d65ff3621b2870a2ef85d980913f319) --- source3/include/debug.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/include/debug.h b/source3/include/debug.h index d47f69db65..55f07d8a18 100644 --- a/source3/include/debug.h +++ b/source3/include/debug.h @@ -35,8 +35,11 @@ /* I know the __attribute__ stuff is ugly, but it does ensure we get the arguemnts to DEBUG() right. We have got them wrong too often in the past. + The PRINTFLIKE comment does the equivalent for SGI MIPSPro. */ +/* PRINTFLIKE1 */ int Debug1( const char *, ... ) PRINTF_ATTRIBUTE(1,2); +/* PRINTFLIKE1 */ BOOL dbgtext( const char *, ... ) PRINTF_ATTRIBUTE(1,2); BOOL dbghdr( int level, const char *file, const char *func, int line ); -- cgit From 8fbd4cdbef394492393005f400af14f66bd6f41a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 9 Feb 2004 18:20:41 +0000 Subject: Expand 'net rpc group members' to local groups. Volker (This used to be commit f524a493154a5f7304be472064550cd61af8305d) --- source3/utils/net_rpc.c | 224 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 175 insertions(+), 49 deletions(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index c7e014131b..30da32ae4e 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1250,68 +1250,36 @@ static int rpc_group_list(int argc, const char **argv) rpc_group_list_internals, argc, argv); } - -static NTSTATUS -rpc_group_members_internals(const DOM_SID *domain_sid, const char *domain_name, - struct cli_state *cli, - TALLOC_CTX *mem_ctx, int argc, const char **argv) + +static NTSTATUS +rpc_list_group_members(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const char *domain_name, const DOM_SID *domain_sid, + POLICY_HND *domain_pol, uint32 rid) { NTSTATUS result; - POLICY_HND connect_pol, domain_pol, group_pol; - uint32 num_rids, *rids, *rid_types; + POLICY_HND group_pol; uint32 num_members, *group_rids, *group_attrs; uint32 num_names; char **names; uint32 *name_types; int i; - /* Get sam policy handle */ - - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - /* Get domain policy handle */ - - result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, - 1, argv, &num_rids, &rids, &rid_types); - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - if (num_rids != 1) { - d_printf("Could not find group %s\n", argv[0]); - goto done; - } - - if (rid_types[0] != SID_NAME_DOM_GRP) { - d_printf("%s is not a domain group\n", argv[0]); - goto done; - } + fstring sid_str; + sid_to_string(sid_str, domain_sid); - result = cli_samr_open_group(cli, mem_ctx, &domain_pol, + result = cli_samr_open_group(cli, mem_ctx, domain_pol, MAXIMUM_ALLOWED_ACCESS, - rids[0], &group_pol); + rid, &group_pol); if (!NT_STATUS_IS_OK(result)) - goto done; + return result; result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol, &num_members, &group_rids, &group_attrs); if (!NT_STATUS_IS_OK(result)) - goto done; + return result; while (num_members > 0) { int this_time = 512; @@ -1319,23 +1287,181 @@ rpc_group_members_internals(const DOM_SID *domain_sid, const char *domain_name, if (num_members < this_time) this_time = num_members; - result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol, 1000, + result = cli_samr_lookup_rids(cli, mem_ctx, domain_pol, 1000, this_time, group_rids, &num_names, &names, &name_types); if (!NT_STATUS_IS_OK(result)) - goto done; + return result; + + /* We only have users as members, but make the output + the same as the output of alias members */ for (i = 0; i < this_time; i++) { - printf("%s\n", names[i]); + + if (opt_long_list_entries) { + printf("%s-%d %s\\%s %d\n", sid_str, + group_rids[i], domain_name, names[i], + SID_NAME_USER); + } else { + printf("%s\\%s\n", domain_name, names[i]); + } } num_members -= this_time; group_rids += 512; } - done: - return result; + return NT_STATUS_OK; +} + +static NTSTATUS +rpc_list_alias_members(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 rid) +{ + NTSTATUS result; + POLICY_HND alias_pol, lsa_pol; + uint32 num_members; + DOM_SID *alias_sids; + char **domains; + char **names; + uint32 *types; + int i; + + result = cli_samr_open_alias(cli, mem_ctx, domain_pol, + MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol); + + if (!NT_STATUS_IS_OK(result)) + return result; + + result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol, + &num_members, &alias_sids); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Couldn't list alias members\n"); + return result; + } + + cli_nt_session_close(cli); + + if (!cli_nt_session_open(cli, PI_LSARPC)) { + d_printf("Couldn't open LSA pipe\n"); + return result; + } + + result = cli_lsa_open_policy(cli, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Couldn't open LSA policy handle\n"); + return result; + } + + result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol, num_members, + alias_sids, + &domains, &names, &types); + + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { + d_printf("Couldn't lookup SIDs\n"); + return result; + } + + for (i = 0; i < num_members; i++) { + fstring sid_str; + sid_to_string(sid_str, &alias_sids[i]); + + if (opt_long_list_entries) { + printf("%s %s\\%s %d\n", sid_str, + domains[i] ? domains[i] : "*unknown*", + names[i] ? names[i] : "*unknown*", types[i]); + } else { + if (domains[i]) + printf("%s\\%s\n", domains[i], names[i]); + else + printf("%s\n", sid_str); + } + } + + return NT_STATUS_OK; +} + +static NTSTATUS +rpc_group_members_internals(const DOM_SID *domain_sid, + const char *domain_name, + struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + NTSTATUS result; + POLICY_HND connect_pol, domain_pol; + uint32 num_rids, *rids, *rid_types; + + /* Get sam policy handle */ + + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + + if (!NT_STATUS_IS_OK(result)) + return result; + + /* Get domain policy handle */ + + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + domain_sid, &domain_pol); + + if (!NT_STATUS_IS_OK(result)) + return result; + + result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, + 1, argv, &num_rids, &rids, &rid_types); + + if (!NT_STATUS_IS_OK(result)) { + + /* Ok, did not find it in the global sam, try with builtin */ + + DOM_SID sid_Builtin; + + cli_samr_close(cli, mem_ctx, &domain_pol); + + string_to_sid(&sid_Builtin, "S-1-5-32"); + + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &sid_Builtin, &domain_pol); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Couldn't find group %s\n", argv[0]); + return result; + } + + result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, + 1, argv, &num_rids, + &rids, &rid_types); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Couldn't find group %s\n", argv[0]); + return result; + } + } + + if (num_rids != 1) { + d_printf("Couldn't find group %s\n", argv[0]); + return result; + } + + if (rid_types[0] == SID_NAME_DOM_GRP) { + return rpc_list_group_members(cli, mem_ctx, domain_name, + domain_sid, &domain_pol, + rids[0]); + } + + if (rid_types[0] == SID_NAME_ALIAS) { + return rpc_list_alias_members(cli, mem_ctx, &domain_pol, + rids[0]); + } + + return NT_STATUS_NO_SUCH_GROUP; } static int rpc_group_members(int argc, const char **argv) -- cgit From 5f4f500df4a28e212527b05850cf44a6fdfe0a0b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 9 Feb 2004 18:47:19 +0000 Subject: bug 1046 (patch from Bostjan Golob ); fix 20 month old bug where getpwent_list() was overoverwriting the username for entries. However the code path to the bug was introduced only on January 25 (This used to be commit fbde889fd8442bae7444ffdb2736c9c5e8d59204) --- source3/lib/util_getent.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/lib/util_getent.c b/source3/lib/util_getent.c index 32641dbf83..3544c1678c 100644 --- a/source3/lib/util_getent.c +++ b/source3/lib/util_getent.c @@ -156,15 +156,15 @@ struct sys_pwent * getpwent_list(void) pent->pw_uid = pwd->pw_uid; pent->pw_gid = pwd->pw_gid; if (pwd->pw_gecos) { - if ((pent->pw_name = strdup(pwd->pw_gecos)) == NULL) + if ((pent->pw_gecos = strdup(pwd->pw_gecos)) == NULL) goto err; } if (pwd->pw_dir) { - if ((pent->pw_name = strdup(pwd->pw_dir)) == NULL) + if ((pent->pw_dir = strdup(pwd->pw_dir)) == NULL) goto err; } if (pwd->pw_shell) { - if ((pent->pw_name = strdup(pwd->pw_shell)) == NULL) + if ((pent->pw_shell = strdup(pwd->pw_shell)) == NULL) goto err; } -- cgit From 2e2b6548200faadecf21d668596835ef160f7adb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 9 Feb 2004 18:48:44 +0000 Subject: merge from 3.0 (This used to be commit 309a9a4cafc3c892840e28198a41973b236a528e) --- examples/VFS/configure.in | 32 ++-- examples/libsmbclient/Makefile | 2 +- examples/nss/wbtest.c | 375 +++++++++++++++++++++++++++++++++++++++++ examples/pdb/mysql/mysql.dump | 4 +- 4 files changed, 395 insertions(+), 18 deletions(-) create mode 100644 examples/nss/wbtest.c diff --git a/examples/VFS/configure.in b/examples/VFS/configure.in index 3799e3a507..fda4cf3a31 100644 --- a/examples/VFS/configure.in +++ b/examples/VFS/configure.in @@ -53,7 +53,7 @@ AC_SUBST(LDSHFLAGS) AC_SUBST(SONAMEFLAG) AC_SUBST(SHLD) AC_SUBST(HOST_OS) -AC_SUBST(PICFLAG) +AC_SUBST(PICFLAGS) AC_SUBST(PICSUFFIX) AC_SUBST(SHLIBEXT) AC_SUBST(INSTALLCLIENTCMD_SH) @@ -178,7 +178,7 @@ HOST_OS="$host_os" LDSHFLAGS="-shared" SONAMEFLAG="#" SHLD="\${CC}" -PICFLAG="" +PICFLAGS="" PICSUFFIX="po" SHLIBEXT="so" @@ -195,7 +195,7 @@ if test "$enable_shared" = "yes"; then BLDSHARED="true" LDSHFLAGS="-shared" DYNEXP="-Wl,--export-dynamic" - PICFLAG="-fPIC" + PICFLAGS="-fPIC" SONAMEFLAG="-Wl,-soname=" ;; *solaris*) @@ -203,12 +203,12 @@ if test "$enable_shared" = "yes"; then LDSHFLAGS="-G" SONAMEFLAG="-h " if test "${GCC}" = "yes"; then - PICFLAG="-fPIC" + PICFLAGS="-fPIC" if test "${ac_cv_prog_gnu_ld}" = "yes"; then DYNEXP="-Wl,-E" fi else - PICFLAG="-KPIC" + PICFLAGS="-KPIC" ## ${CFLAGS} added for building 64-bit shared ## libs using Sun's Compiler LDSHFLAGS="-G \${CFLAGS}" @@ -219,19 +219,19 @@ if test "$enable_shared" = "yes"; then BLDSHARED="true" LDSHFLAGS="-G" SONAMEFLAG="-Wl,-h," - PICFLAG="-KPIC" # Is this correct for SunOS + PICFLAGS="-KPIC" # Is this correct for SunOS ;; *netbsd* | *freebsd*) BLDSHARED="true" LDSHFLAGS="-shared" DYNEXP="-Wl,--export-dynamic" SONAMEFLAG="-Wl,-soname," - PICFLAG="-fPIC -DPIC" + PICFLAGS="-fPIC -DPIC" ;; *openbsd*) BLDSHARED="true" LDSHFLAGS="-shared" DYNEXP="-Wl,-Bdynamic" SONAMEFLAG="-Wl,-soname," - PICFLAG="-fPIC" + PICFLAGS="-fPIC" ;; *irix*) case "$host_os" in @@ -244,16 +244,16 @@ if test "$enable_shared" = "yes"; then SONAMEFLAG="-soname " SHLD="\${LD}" if test "${GCC}" = "yes"; then - PICFLAG="-fPIC" + PICFLAGS="-fPIC" else - PICFLAG="-KPIC" + PICFLAGS="-KPIC" fi ;; *aix*) BLDSHARED="true" LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry,-berok" DYNEXP="-Wl,-brtl,-bexpall" - PICFLAG="-O2" + PICFLAGS="-O2" if test "${GCC}" != "yes"; then ## for funky AIX compiler using strncpy() CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000" @@ -267,7 +267,7 @@ if test "$enable_shared" = "yes"; then SHLD="/usr/bin/ld" LDSHFLAGS="-B symbolic -b -z" SONAMEFLAG="+h " - PICFLAG="+z" + PICFLAGS="+z" fi DYNEXP="-Wl,-E" ;; @@ -277,7 +277,7 @@ if test "$enable_shared" = "yes"; then BLDSHARED="true" LDSHFLAGS="-shared" SONAMEFLAG="-Wl,-soname," - PICFLAG="-fPIC" + PICFLAGS="-fPIC" ;; *sco*) ;; @@ -285,7 +285,7 @@ if test "$enable_shared" = "yes"; then BLDSHARED="true" LDSHFLAGS="-shared" SONAMEFLAG="-Wl,-soname," - PICFLAG="-KPIC" + PICFLAGS="-KPIC" ;; *next2*) ;; @@ -328,11 +328,11 @@ AC_CACHE_CHECK([whether building shared libraries actually works], ac_cv_shlib_works=no # try building a trivial shared library if test "$PICSUFFIX" = "po"; then - $CC $CPPFLAGS $CFLAGS $PICFLAG -c -o shlib.po ${srcdir-.}/tests/shlib.c && + $CC $CPPFLAGS $CFLAGS $PICFLAGS -c -o shlib.po ${srcdir-.}/tests/shlib.c && $CC $CPPFLAGS $CFLAGS `eval echo $LDSHFLAGS` -o "shlib.$SHLIBEXT" shlib.po && ac_cv_shlib_works=yes else - $CC $CPPFLAGS $CFLAGS $PICFLAG -c -o shlib.$PICSUFFIX ${srcdir-.}/tests/shlib.c && + $CC $CPPFLAGS $CFLAGS $PICFLAGS -c -o shlib.$PICSUFFIX ${srcdir-.}/tests/shlib.c && mv shlib.$PICSUFFIX shlib.po && $CC $CPPFLAGS $CFLAGS `eval echo $LDSHFLAGS` -o "shlib.$SHLIBEXT" shlib.po && ac_cv_shlib_works=yes diff --git a/examples/libsmbclient/Makefile b/examples/libsmbclient/Makefile index c84cc3c977..e7c82a3aee 100644 --- a/examples/libsmbclient/Makefile +++ b/examples/libsmbclient/Makefile @@ -14,7 +14,7 @@ all: testsmbc tree testacl testsmbc: testsmbc.o @echo Linking testsmbc - @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lsmbclient -L/usr/local/lib + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lsmbclient -L/usr/local/lib testsmbc-static: testsmbc.o @echo Linking testsmbc diff --git a/examples/nss/wbtest.c b/examples/nss/wbtest.c new file mode 100644 index 0000000000..fc8f575ef0 --- /dev/null +++ b/examples/nss/wbtest.c @@ -0,0 +1,375 @@ +/* + nss sample code for extended winbindd functionality + + Copyright (C) Andrew Tridgell (tridge@samba.org) + + you are free to use this code in any way you see fit, including + without restriction, using this code in your own products. You do + not need to give any attribution. +*/ + +/* + compile like this: + + cc -o wbtest wbtest.c -ldl + + and run like this: + + ./wbtest /lib/libnss_winbind.so +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef enum nss_status NSS_STATUS; + +struct nss_state { + void *dl_handle; + char *nss_name; + char pwnam_buf[512]; +}; + +/* + find a function in the nss library +*/ +static void *find_fn(struct nss_state *nss, const char *name) +{ + void *res; + char *s = NULL; + + asprintf(&s, "_nss_%s_%s", nss->nss_name, name); + if (!s) { + errno = ENOMEM; + return NULL; + } + res = dlsym(nss->dl_handle, s); + free(s); + if (!res) { + errno = ENOENT; + return NULL; + } + return res; +} + +/* + establish a link to the nss library + Return 0 on success and -1 on error +*/ +int nss_open(struct nss_state *nss, const char *nss_path) +{ + char *p; + p = strrchr(nss_path, '_'); + if (!p) { + errno = EINVAL; + return -1; + } + + nss->nss_name = strdup(p+1); + p = strchr(nss->nss_name, '.'); + if (p) *p = 0; + + nss->dl_handle = dlopen(nss_path, RTLD_LAZY); + if (!nss->dl_handle) { + free(nss->nss_name); + return -1; + } + + return 0; +} + +/* + close and cleanup a nss state +*/ +void nss_close(struct nss_state *nss) +{ + free(nss->nss_name); + dlclose(nss->dl_handle); +} + +/* + make a getpwnam call. + Return 0 on success and -1 on error +*/ +int nss_getpwent(struct nss_state *nss, struct passwd *pwd) +{ + NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *, + size_t , int *) = find_fn(nss, "getpwent_r"); + NSS_STATUS status; + int nss_errno = 0; + + if (!_nss_getpwent_r) { + return -1; + } + + status = _nss_getpwent_r(pwd, nss->pwnam_buf, sizeof(nss->pwnam_buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + return 0; +} + +/* + make a setpwent call. + Return 0 on success and -1 on error +*/ +int nss_setpwent(struct nss_state *nss) +{ + NSS_STATUS (*_nss_setpwent)(void) = find_fn(nss, "setpwent"); + NSS_STATUS status; + if (!_nss_setpwent) { + return -1; + } + status = _nss_setpwent(); + if (status != NSS_STATUS_SUCCESS) { + errno = EINVAL; + return -1; + } + return 0; +} + +/* + make a endpwent call. + Return 0 on success and -1 on error +*/ +int nss_endpwent(struct nss_state *nss) +{ + NSS_STATUS (*_nss_endpwent)(void) = find_fn(nss, "endpwent"); + NSS_STATUS status; + if (!_nss_endpwent) { + return -1; + } + status = _nss_endpwent(); + if (status != NSS_STATUS_SUCCESS) { + errno = EINVAL; + return -1; + } + return 0; +} + + +/* + convert a name to a SID + caller frees + Return 0 on success and -1 on error +*/ +int nss_nametosid(struct nss_state *nss, const char *name, char **sid) +{ + NSS_STATUS (*_nss_nametosid)(const char *, char **, char *, size_t, int *) = + find_fn(nss, "nametosid"); + NSS_STATUS status; + int nss_errno = 0; + char buf[200]; + + if (!_nss_nametosid) { + return -1; + } + + status = _nss_nametosid(name, sid, buf, sizeof(buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + *sid = strdup(*sid); + + return 0; +} + +/* + convert a SID to a name + caller frees + Return 0 on success and -1 on error +*/ +int nss_sidtoname(struct nss_state *nss, char *sid, char **name) +{ + NSS_STATUS (*_nss_sidtoname)(const char *, char **, char *, size_t, int *) = + find_fn(nss, "sidtoname"); + NSS_STATUS status; + int nss_errno = 0; + char buf[200]; + + if (!_nss_sidtoname) { + return -1; + } + + status = _nss_sidtoname(sid, name, buf, sizeof(buf), &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + return -1; + } + if (status != NSS_STATUS_SUCCESS) { + errno = nss_errno; + return -1; + } + + *name = strdup(*name); + + return 0; +} + +/* + return a list of group SIDs for a user SID + the returned list is NULL terminated + Return 0 on success and -1 on error +*/ +int nss_getusersids(struct nss_state *nss, const char *user_sid, char ***sids) +{ + NSS_STATUS (*_nss_getusersids)(const char *, char **, int *, char *, size_t, int *) = + find_fn(nss, "getusersids"); + NSS_STATUS status; + int nss_errno = 0; + char *s; + int i, num_groups = 0; + unsigned bufsize = 10; + char *buf; + + if (!_nss_getusersids) { + return -1; + } + +again: + buf = malloc(bufsize); + if (!buf) { + errno = ENOMEM; + return -1; + } + + status = _nss_getusersids(user_sid, &s, &num_groups, buf, bufsize, &nss_errno); + if (status == NSS_STATUS_NOTFOUND) { + errno = ENOENT; + free(buf); + return -1; + } + + if (status == NSS_STATUS_TRYAGAIN) { + bufsize *= 2; + free(buf); + goto again; + } + + if (status != NSS_STATUS_SUCCESS) { + free(buf); + errno = nss_errno; + return -1; + } + + if (num_groups == 0) { + free(buf); + return 0; + } + + *sids = (char **)malloc(sizeof(char *) * (num_groups+1)); + if (! *sids) { + errno = ENOMEM; + free(buf); + return -1; + } + + for (i=0;iname %s\n", name2); + + if (nss_getusersids(nss, sid, &group_sids) != 0) { + perror("getusersids"); + return -1; + } + + printf("\tGroups:\n"); + for (i=0; group_sids[i]; i++) { + printf("\t\t%s\n", group_sids[i]); + free(group_sids[i]); + } + + free(sid); + free(name2); + free(group_sids); + } + + + if (nss_endpwent(nss) != 0) { + perror("endpwent"); + return -1; + } + + return 0; +} + + +/* + main program. It lists all users, listing user SIDs for each user + */ +int main(int argc, char *argv[]) +{ + struct nss_state nss; + const char *so_path = "/lib/libnss_winbind.so"; + int ret; + + if (argc > 1) { + so_path = argv[1]; + } + + if (nss_open(&nss, so_path) != 0) { + perror("nss_open"); + exit(1); + } + + ret = nss_test_users(&nss); + + nss_close(&nss); + + return ret; +} diff --git a/examples/pdb/mysql/mysql.dump b/examples/pdb/mysql/mysql.dump index 3bd6d19800..5da75f5745 100644 --- a/examples/pdb/mysql/mysql.dump +++ b/examples/pdb/mysql/mysql.dump @@ -31,5 +31,7 @@ CREATE TABLE user ( logon_divs int(9), hours_len int(9), unknown_5 int(9), - unknown_6 int(9) + unknown_6 int(9), + bad_password_count int(9), + logon_count(9) ); -- cgit From da426ad4bf366c248304cea962530105f585f173 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 9 Feb 2004 18:49:22 +0000 Subject: add smbget to cvs ignore list (This used to be commit 1e8bbd2961f8216ade50cabdbad3d216c8d77819) --- source3/bin/.cvsignore | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/source3/bin/.cvsignore b/source3/bin/.cvsignore index aad6091960..3144075134 100644 --- a/source3/bin/.cvsignore +++ b/source3/bin/.cvsignore @@ -1,8 +1,7 @@ -*.so -.dummy -.libs debug2html +.dummy editreg +.libs locktest locktest2 log2pcap @@ -28,6 +27,7 @@ smbcontrol smbcquotas smbd smbfilter +smbget smbgroupedit smbiconv smbmnt @@ -39,16 +39,17 @@ smbstatus smbtorture smbtree smbumount +*.so swat -t_push_ucs2 -t_snprintf -t_strcmp -t_stringoverflow talloctort tdbbackup tdbdump testparm testprns +t_push_ucs2 +t_snprintf +t_strcmp +t_stringoverflow vfstest wbinfo winbindd -- cgit From 00be82c1c89d210cdc269e74356698cbd23d3a32 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 10 Feb 2004 00:17:18 +0000 Subject: Fix compiler warning. rafal (This used to be commit e92fb5dcb02a56d10230df70d495f91da4052e62) --- source3/passdb/machine_sid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c index 1fb3569f76..21ae95af5b 100644 --- a/source3/passdb/machine_sid.c +++ b/source3/passdb/machine_sid.c @@ -201,7 +201,8 @@ DOM_SID *get_global_sam_sid(void) /** * Force get_global_sam_sid to requery the backends */ -void reset_global_sam_sid() +void reset_global_sam_sid(void) { SAFE_FREE(global_sam_sid); } + -- cgit From 1eaa54092b135aeef619a4ce998f733ea796dd47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 10 Feb 2004 02:21:41 +0000 Subject: Fix for possible crash bug from Sebastian Krahmer (SuSE). Jeremy. (This used to be commit e7a25c1e2ea2ff980f4aecf94f65563316976997) --- source3/libsmb/ntlmssp_parse.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 3444db0306..4b3043aec8 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -216,7 +216,9 @@ BOOL msrpc_parse(const DATA_BLOB *blob, /* if odd length and unicode */ return False; } - + if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + return False; + if (0 < len1) { pull_string(NULL, p, blob->data + ptr, sizeof(p), len1, @@ -241,7 +243,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } - + + if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + return False; + if (0 < len1) { pull_string(NULL, p, blob->data + ptr, sizeof(p), len1, @@ -266,6 +271,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } + + if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + return False; + *b = data_blob(blob->data + ptr, len1); } break; @@ -274,6 +283,9 @@ BOOL msrpc_parse(const DATA_BLOB *blob, len1 = va_arg(ap, unsigned); /* make sure its in the right format - be strict */ NEED_DATA(len1); + if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) + return False; + *b = data_blob(blob->data + head_ofs, len1); head_ofs += len1; break; @@ -284,6 +296,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, break; case 'C': s = va_arg(ap, char *); + + if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) + return False; + head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), blob->length - head_ofs, STR_ASCII|STR_TERMINATE); -- cgit From ffce0e466642134bd4556a91310761630400ed03 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 10 Feb 2004 03:51:30 +0000 Subject: fix more compiler warning after the latest static rampage (This used to be commit 98d9278c81ede2a931a2c2c8371c0499601a1457) --- source3/nsswitch/winbindd_util.c | 56 ++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index eecb36a30f..403ba399c8 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -168,34 +168,6 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const return domain; } -/******************************************************************** - Periodically we need to refresh the trusted domain cache for smbd -********************************************************************/ - -void rescan_trusted_domains( void ) -{ - time_t now = time(NULL); - struct winbindd_domain *mydomain = NULL; - - /* see if the time has come... */ - - if ( (now > last_trustdom_scan) && ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) ) - return; - - if ( (mydomain = find_our_domain()) == NULL ) { - DEBUG(0,("rescan_trusted_domains: Can't find my own domain!\n")); - return; - } - - /* this will only add new domains we didn't already know about */ - - add_trusted_domains( mydomain ); - - last_trustdom_scan = now; - - return; -} - /******************************************************************** rescan our domains looking for new trusted domains ********************************************************************/ @@ -271,6 +243,34 @@ static void add_trusted_domains( struct winbindd_domain *domain ) talloc_destroy(mem_ctx); } +/******************************************************************** + Periodically we need to refresh the trusted domain cache for smbd +********************************************************************/ + +void rescan_trusted_domains( void ) +{ + time_t now = time(NULL); + struct winbindd_domain *mydomain = NULL; + + /* see if the time has come... */ + + if ( (now > last_trustdom_scan) && ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) ) + return; + + if ( (mydomain = find_our_domain()) == NULL ) { + DEBUG(0,("rescan_trusted_domains: Can't find my own domain!\n")); + return; + } + + /* this will only add new domains we didn't already know about */ + + add_trusted_domains( mydomain ); + + last_trustdom_scan = now; + + return; +} + /* Look up global info for the winbind daemon */ BOOL init_domain_list(void) { -- cgit From c2d30222c6d9f2068ffd5835a0b45d35378d72e1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 10 Feb 2004 04:04:24 +0000 Subject: merge fixes from 3.0 (This used to be commit ea75f34eef90e410045fe4d32052cbea483a27da) --- source3/lib/util_sock.c | 50 ++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 12c748e5f2..782f5f3f73 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -29,6 +29,29 @@ int lastport=0; int smb_read_error = 0; +static char *get_socket_addr(int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + int length = sizeof(sa); + static fstring addr_buf; + + fstrcpy(addr_buf,"0.0.0.0"); + + if (fd == -1) { + return addr_buf; + } + + if (getsockname(fd, &sa, &length) < 0) { + DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); + return addr_buf; + } + + fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); + + return addr_buf; +} + /**************************************************************************** Determine if a file descriptor is in fact a socket. ****************************************************************************/ @@ -552,6 +575,10 @@ BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout) smb_read_error = READ_ERROR; return False; } + + /* not all of samba3 properly checks for packet-termination of strings. This + ensures that we don't run off into empty space. */ + SSVAL(buffer+4,len, 0); } return True; @@ -954,29 +981,6 @@ char *get_peer_addr(int fd) return addr_buf; } -static char *get_socket_addr(int fd) -{ - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - int length = sizeof(sa); - static fstring addr_buf; - - fstrcpy(addr_buf,"0.0.0.0"); - - if (fd == -1) { - return addr_buf; - } - - if (getsockname(fd, &sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) )); - return addr_buf; - } - - fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); - - return addr_buf; -} - /******************************************************************* Create protected unix domain socket. -- cgit From 860d85862f7f9538f34f987a8228e9bfa8d46463 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 11 Feb 2004 04:32:53 +0000 Subject: marking 'only user' as deprecated (based on feedback in bug 66) (This used to be commit b94ca7e7be7a6f0674cafa76bf30a46f2f36bd8f) --- source3/param/loadparm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index e0c6f821a1..ae9d3ae945 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -855,7 +855,7 @@ static struct parm_struct parm_table[] = { {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE}, - {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, + {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED}, {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE}, {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, -- cgit From 1a3421b18e3adb274f990c75ba099ba8fc457a7d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 11 Feb 2004 10:02:48 +0000 Subject: Move around function to fix build after recent static rampage. (This used to be commit 1ab42df4a648fc19391891163d891c4bdb23437e) --- source3/passdb/passdb.c | 125 ++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index d45450a4fd..d0a1711f0f 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -189,6 +189,68 @@ NTSTATUS pdb_init_sam(SAM_ACCOUNT **user) return NT_STATUS_OK; } +/************************************************************************** + * This function will take care of all the steps needed to correctly + * allocate and set the user SID, please do use this function to create new + * users, messing with SIDs is not good. + * + * account_data must be provided initialized, pwd may be null. + * SSS + ***************************************************************************/ + +static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd) +{ + const char *guest_account = lp_guestaccount(); + GROUP_MAP map; + BOOL ret; + + if (!account_data || !pwd) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* this is a hack this thing should not be set + this way --SSS */ + if (!(guest_account && *guest_account)) { + DEBUG(1, ("NULL guest account!?!?\n")); + return NT_STATUS_UNSUCCESSFUL; + } else { + /* Ensure this *must* be set right */ + if (strcmp(pwd->pw_name, guest_account) == 0) { + if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) { + return NT_STATUS_UNSUCCESSFUL; + } + if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) { + return NT_STATUS_UNSUCCESSFUL; + } + return NT_STATUS_OK; + } + } + + if (!pdb_set_user_sid_from_rid(account_data, fallback_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) { + DEBUG(0,("Can't set User SID from RID!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* call the mapping code here */ + become_root(); + ret = pdb_getgrgid(&map, pwd->pw_gid); + unbecome_root(); + + if( ret ) { + if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){ + DEBUG(0,("Can't set Group SID!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + } + else { + if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) { + DEBUG(0,("Can't set Group SID\n")); + return NT_STATUS_INVALID_PARAMETER; + } + } + + return NT_STATUS_OK; +} /************************************************************* Initialises a struct sam_passwd with sane values. @@ -403,69 +465,6 @@ NTSTATUS pdb_free_sam(SAM_ACCOUNT **user) return NT_STATUS_OK; } -/************************************************************************** - * This function will take care of all the steps needed to correctly - * allocate and set the user SID, please do use this function to create new - * users, messing with SIDs is not good. - * - * account_data must be provided initialized, pwd may be null. - * SSS - ***************************************************************************/ - -static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd) -{ - const char *guest_account = lp_guestaccount(); - GROUP_MAP map; - BOOL ret; - - if (!account_data || !pwd) { - return NT_STATUS_INVALID_PARAMETER; - } - - /* this is a hack this thing should not be set - this way --SSS */ - if (!(guest_account && *guest_account)) { - DEBUG(1, ("NULL guest account!?!?\n")); - return NT_STATUS_UNSUCCESSFUL; - } else { - /* Ensure this *must* be set right */ - if (strcmp(pwd->pw_name, guest_account) == 0) { - if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) { - return NT_STATUS_UNSUCCESSFUL; - } - if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) { - return NT_STATUS_UNSUCCESSFUL; - } - return NT_STATUS_OK; - } - } - - if (!pdb_set_user_sid_from_rid(account_data, fallback_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) { - DEBUG(0,("Can't set User SID from RID!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* call the mapping code here */ - become_root(); - ret = pdb_getgrgid(&map, pwd->pw_gid); - unbecome_root(); - - if( ret ) { - if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){ - DEBUG(0,("Can't set Group SID!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - } - else { - if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) { - DEBUG(0,("Can't set Group SID\n")); - return NT_STATUS_INVALID_PARAMETER; - } - } - - return NT_STATUS_OK; -} - /********************************************************** Encode the account control bits into a string. length = length of string to encode into (including terminating -- cgit From 49a9596c6223573a6a38cf310d366e713a3c1555 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 11 Feb 2004 10:30:46 +0000 Subject: Applied James Peach's stack backtrace patch for IRIX. (This used to be commit 056bf382d748ca06a1937ee19b0193430199f63b) --- source3/configure.in | 4 ++++ source3/lib/util.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/source3/configure.in b/source3/configure.in index 38f908007c..7cc42fe5bd 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -921,6 +921,10 @@ AC_CHECK_FUNCS(setlocale nl_langinfo) # setbuffer, shmget, shm_open are needed for smbtorture AC_CHECK_FUNCS(setbuffer shmget shm_open backtrace_symbols) +# IRIX stack backtrace +AC_CHECK_HEADERS(libexc.h) +AC_CHECK_LIB(exc, trace_back_stack) + # syscall() is needed for smbwrapper. AC_CHECK_FUNCS(syscall) diff --git a/source3/lib/util.c b/source3/lib/util.c index 3da4e536e0..e9ab72b2bf 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1344,6 +1344,10 @@ gid_t nametogid(const char *name) Something really nasty happened - panic ! ********************************************************************/ +#ifdef HAVE_LIBEXC_H +#include +#endif + void smb_panic(const char *why) { char *cmd; @@ -1398,6 +1402,42 @@ void smb_panic(const char *why) SAFE_FREE(backtrace_strings); } +#elif HAVE_LIBEXC + +#define NAMESIZE 32 /* Arbitrary */ + + /* The IRIX libexc library provides an API for unwinding the stack. See + * libexc(3) for details. Apparantly trace_back_stack leaks memory, but + * since we are about to abort anyway, it hardly matters. + * + * Note that if we paniced due to a SIGSEGV or SIGBUS (or similar) this + * will fail with a nasty message upon failing to open the /proc entry. + */ + { + __uint64_t addrs[BACKTRACE_STACK_SIZE]; + char * names[BACKTRACE_STACK_SIZE]; + char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE]; + + int i; + int levels; + + ZERO_ARRAY(addrs); + ZERO_ARRAY(names); + ZERO_ARRAY(namebuf); + + for (i = 0; i < BACKTRACE_STACK_SIZE; i++) { + names[i] = namebuf + (i * NAMESIZE); + } + + levels = trace_back_stack(0, addrs, names, + BACKTRACE_STACK_SIZE, NAMESIZE); + + DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels)); + for (i = 0; i < levels; i++) { + DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i])); + } + } +#undef NAMESIZE #endif dbgflush(); -- cgit From b11fa6146ba9f2a51d495e859357e182a18a7e84 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 11 Feb 2004 15:20:17 +0000 Subject: fix broken compile after andrew's changes (This used to be commit c77baee0f17fd44e333c8db6a9cae33f649a6701) --- source3/sam/gums_api.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/sam/gums_api.c b/source3/sam/gums_api.c index f90cbbc951..5aafa7695f 100644 --- a/source3/sam/gums_api.c +++ b/source3/sam/gums_api.c @@ -346,7 +346,7 @@ const DATA_BLOB gums_get_user_nt_pwd(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return data_blob(NULL, 0); - smbpasswd_sethexpwd(p, (unsigned char *)(obj->user->nt_pw.data), 0); + pdb_sethexpwd(p, (unsigned char *)(obj->user->nt_pw.data), 0); DEBUG(100, ("Reading NT Password=[%s]\n", p)); return obj->user->nt_pw; @@ -359,7 +359,7 @@ const DATA_BLOB gums_get_user_lm_pwd(const GUMS_OBJECT *obj) if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) return data_blob(NULL, 0); - smbpasswd_sethexpwd(p, (unsigned char *)(obj->user->lm_pw.data), 0); + pdb_sethexpwd(p, (unsigned char *)(obj->user->lm_pw.data), 0); DEBUG(100, ("Reading LM Password=[%s]\n", p)); return obj->user->lm_pw; @@ -586,7 +586,7 @@ NTSTATUS gums_set_user_nt_pwd(GUMS_OBJECT *obj, const DATA_BLOB nt_pwd) obj->user->nt_pw = data_blob_talloc(obj->mem_ctx, nt_pwd.data, nt_pwd.length); memcpy(r, nt_pwd.data, 16); - smbpasswd_sethexpwd(p, r, 0); + pdb_sethexpwd(p, r, 0); DEBUG(100, ("Setting NT Password=[%s]\n", p)); return NT_STATUS_OK; @@ -606,7 +606,7 @@ NTSTATUS gums_set_user_lm_pwd(GUMS_OBJECT *obj, const DATA_BLOB lm_pwd) obj->user->lm_pw = data_blob_talloc(obj->mem_ctx, lm_pwd.data, lm_pwd.length); memcpy(r, lm_pwd.data, 16); - smbpasswd_sethexpwd(p, r, 0); + pdb_sethexpwd(p, r, 0); DEBUG(100, ("Setting LM Password=[%s]\n", p)); return NT_STATUS_OK; -- cgit From dad12f62ff1828fc4ee05cae2e2b27931e1d396b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 11 Feb 2004 15:20:41 +0000 Subject: BUG 1055; patch from SATOH Fumiyasu ; formatting fixes for 'net share' (This used to be commit 447d4fee6c245a5bbf0c33c8ffb0fd9041e51c24) --- source3/utils/net_rap.c | 7 ++++--- source3/utils/net_rpc.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/source3/utils/net_rap.c b/source3/utils/net_rap.c index 1f6c6e7a84..39254641ab 100644 --- a/source3/utils/net_rap.c +++ b/source3/utils/net_rap.c @@ -153,14 +153,14 @@ int net_rap_share_usage(int argc, const char **argv) static void long_share_fn(const char *share_name, uint32 type, const char *comment, void *state) { - d_printf("%-12.12s %-8.8s %-50.50s\n", + d_printf("%-12s %-8.8s %-50s\n", share_name, share_type[type], comment); } static void share_fn(const char *share_name, uint32 type, const char *comment, void *state) { - d_printf("%-12.12s\n", share_name); + d_printf("%s\n", share_name); } static int rap_share_delete(int argc, const char **argv) @@ -240,8 +240,9 @@ int net_rap_share(int argc, const char **argv) "\nShare name Type Description\n"\ "---------- ---- -----------\n"); ret = cli_RNetShareEnum(cli, long_share_fn, NULL); + } else { + ret = cli_RNetShareEnum(cli, share_fn, NULL); } - ret = cli_RNetShareEnum(cli, share_fn, NULL); cli_shutdown(cli); return ret; } diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 30da32ae4e..b92d7ec81e 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1623,10 +1623,10 @@ static void display_share_info_1(SRV_SHARE_INFO_1 *info1) rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark); if (opt_long_list_entries) { - d_printf("%-12.12s %-8.8s %-50.50s\n", + d_printf("%-12s %-8.8s %-50s\n", netname, share_type[info1->info_1.type], remark); } else { - d_printf("%-12.12s\n", netname); + d_printf("%s\n", netname); } } -- cgit From 899a09d713d42ca7ffcf78f828e1bac558d54332 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 11 Feb 2004 15:39:11 +0000 Subject: BUG 900: TAKEDA yasuma \n"); return 1; } @@ -1649,8 +1649,8 @@ static int cmd_symlink(void) pstrcpy(src,cur_dir); pstrcpy(dest,cur_dir); - if (!next_token(NULL,buf,NULL,sizeof(buf)) || - !next_token(NULL,buf2,NULL, sizeof(buf2))) { + if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || + !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) { d_printf("symlink \n"); return 1; } @@ -1684,8 +1684,8 @@ static int cmd_chmod(void) pstrcpy(src,cur_dir); - if (!next_token(NULL,buf,NULL,sizeof(buf)) || - !next_token(NULL,buf2,NULL, sizeof(buf2))) { + if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || + !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) { d_printf("chmod mode file\n"); return 1; } @@ -1720,9 +1720,9 @@ static int cmd_chown(void) pstrcpy(src,cur_dir); - if (!next_token(NULL,buf,NULL,sizeof(buf)) || - !next_token(NULL,buf2,NULL, sizeof(buf2)) || - !next_token(NULL,buf3,NULL, sizeof(buf3))) { + if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || + !next_token_nr(NULL,buf2,NULL, sizeof(buf2)) || + !next_token_nr(NULL,buf3,NULL, sizeof(buf3))) { d_printf("chown uid gid file\n"); return 1; } -- cgit From c177b9ef11f0e3048684824bf1cd08a5bd1f975f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Feb 2004 19:59:14 +0000 Subject: Paranoia fixes :-). Jeremy. (This used to be commit 35bbc818ad28c3591df9d5cb0a674802f3f29e1a) --- source3/libsmb/asn1.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 576491dd3b..17170b015f 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -365,6 +365,10 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) int len; if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = True; + return False; + } *s = malloc(len+1); if (! *s) { data->has_error = True; @@ -383,6 +387,10 @@ BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) ZERO_STRUCTP(blob); if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = True; + return False; + } *blob = data_blob(NULL, len); asn1_read(data, blob->data, len); asn1_end_tag(data); -- cgit From ed1862b3b21d1cbe4a013838bf5c581c600657c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Feb 2004 23:25:49 +0000 Subject: More paranoia checks. Jeremy. (This used to be commit 4920f9bd660e22c8ac3ba1c389781f2efbcd1e78) --- source3/libsmb/asn1.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 17170b015f..ecc5e3dee6 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -219,6 +219,11 @@ BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) /* read from a ASN1 buffer, advancing the buffer pointer */ BOOL asn1_read(ASN1_DATA *data, void *p, int len) { + if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) { + data->has_error = True; + return False; + } + if (data->ofs + len > data->length) { data->has_error = True; return False; -- cgit From 30d707b8ae4c53140e0215090f7a3c8936ab2b47 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 12 Feb 2004 05:59:03 +0000 Subject: tdbsam & smb_panic merge from 3.0 (initial tests are ok but I'll setup a HEAD PDC tomorrow) (This used to be commit c57b24ee49aee0f0687742da7f8d741c62f6effe) --- source3/Makefile.in | 98 +++++++++++++------------- source3/lib/dummysmbd.c | 29 ++++++++ source3/lib/util.c | 14 +++- source3/locking/brlock.c | 4 +- source3/locking/locking.c | 4 +- source3/passdb/pdb_tdb.c | 156 +++++++++++++++++++++++++++-------------- source3/printing/printing_db.c | 3 +- source3/smbd/connection.c | 8 +-- source3/smbd/server.c | 2 + source3/smbd/session.c | 4 +- source3/smbd/tdbutil.c | 85 ++++++++++++++++++++++ 11 files changed, 295 insertions(+), 112 deletions(-) create mode 100644 source3/lib/dummysmbd.c create mode 100644 source3/smbd/tdbutil.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 77ae8a0bdd..886d9f81a9 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -190,6 +190,8 @@ LIB_OBJ = lib/version.o lib/charcnv.o lib/debug.o lib/fault.o \ LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o +LIB_NONSMBD_OBJ = $(LIB_OBJ) lib/dummysmbd.o + READLINE_OBJ = lib/readline.o # Also depends on $(SECRETS_OBJ) $(LIBSAMBA_OBJ) @@ -286,7 +288,7 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \ RPC_CLIENT_OBJ = rpc_client/cli_pipe.o -LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o +LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o smbd/tdbutil.o GUMS_OBJ = sam/gums.o sam/gums_api.o sam/gums_helper.o @GUMS_STATIC@ @@ -377,11 +379,11 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(MSDFS_OBJ) $(LIBSMB_OBJ) \ $(UBIQX_OBJ) $(BUILDOPT_OBJ) $(SMBLDAP_OBJ) PRINTING_OBJ = printing/pcap.o printing/print_svid.o \ - printing/print_cups.o printing/print_generic.o \ - printing/lpq_parse.o printing/load.o + printing/print_cups.o printing/print_generic.o \ + printing/lpq_parse.o printing/load.o PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o printing/notify.o \ - printing/printing_db.o + printing/printing_db.o MSDFS_OBJ = msdfs/msdfs.o @@ -400,13 +402,13 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \ nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) \ - $(PROFILE_OBJ) $(LIB_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) + $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) WREPL_OBJ1 = wrepld/server.o wrepld/process.o wrepld/parser.o wrepld/socket.o \ wrepld/partners.o WREPL_OBJ = $(WREPL_OBJ1) $(PARAM_OBJ) $(UBIQX_OBJ) \ - $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) \ + $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) \ $(LIBSAMBA_OBJ) SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \ @@ -414,39 +416,41 @@ SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \ - $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \ - $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) libsmb/passchange.o lib/dummyroot.o + $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \ + $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) \ + libsmb/passchange.o lib/dummyroot.o SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \ - $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) + $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \ - $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) \ + $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ $(SECRETS_OBJ) $(LIBSAMBA_OBJ) lib/dummyroot.o libsmb/errormap.o + SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \ - $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) \ + $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ $(SECRETS_OBJ) $(LIBSAMBA_OBJ) \ printing/notify.o printing/printing_db.o lib/dummyroot.o libsmb/errormap.o -SMBTREE_OBJ = utils/smbtree.o $(LOCKING_OBJ) $(PARAM_OBJ) \ - $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) \ +SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \ + $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \ $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) TESTPARM_OBJ = utils/testparm.o \ - $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) \ + $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ $(SECRETS_OBJ) $(LIBSAMBA_OBJ) TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \ - $(LIB_OBJ) + $(LIB_NONSMBD_OBJ) SMBPASSWD_OBJ = utils/smbpasswd.o libsmb/passchange.o $(PARAM_OBJ) $(SECRETS_OBJ) \ $(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\ - $(UBIQX_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ) \ + $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \ $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) lib/dummyroot.o PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \ - $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \ + $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ) $(SECRETS_OBJ) @@ -460,7 +464,7 @@ RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_epmapper.o RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ - $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ + $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) \ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \ $(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \ @@ -476,7 +480,7 @@ SMBW_OBJ1 = smbwrapper/smbw.o \ smbwrapper/smbw_cache.o SMBW_OBJ = $(SMBW_OBJ1) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(PARAM_OBJ) \ - $(UBIQX_OBJ) $(LIB_OBJ) + $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) SMBWRAPPER_OBJ1 = smbwrapper/wrapped.o @@ -484,7 +488,7 @@ SMBWRAPPER_OBJ = $(SMBW_OBJ) $(SMBWRAPPER_OBJ1) LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \ libsmb/libsmb_cache.o \ - $(PARAM_OBJ) $(LIB_OBJ) \ + $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) \ $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) @@ -494,7 +498,7 @@ LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \ LIBBIGBALLOFMUD_MAJOR = 0 -LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \ +LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \ $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \ $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o @@ -503,7 +507,7 @@ LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.@PICSUFFIX@) CLIENT_OBJ1 = client/client.o client/clitar.o CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \ - $(LIB_OBJ) $(KRBCLIENT_OBJ) \ + $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \ $(READLINE_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \ @@ -514,62 +518,62 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ - $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ + $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) \ $(LIBMSRPC_OBJ) $(IDMAP_OBJ) \ $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \ $(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o lib/server_mutex.o lib/afs.o CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \ - $(LIB_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ) + $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ) MOUNT_OBJ = client/smbmount.o \ - $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) + $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) MNT_OBJ = client/smbmnt.o lib/version.o lib/snprintf.o UMOUNT_OBJ = client/smbumount.o NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBNMB_OBJ) \ - $(LIB_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ) + $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ) SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/utable.o \ torture/denytest.o torture/mangle_test.o SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \ - $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) + $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ - $(UBIQX_OBJ) $(LIB_OBJ) + $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ - $(UBIQX_OBJ) $(LIB_OBJ) + $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \ - $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) + $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) lib/dummyroot.o NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ - $(UBIQX_OBJ) $(LIB_OBJ) + $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) VFSTEST_OBJ = torture/cmd_vfs.o torture/vfstest.o $(SMBD_OBJ_BASE) $(READLINE_OBJ) -SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_OBJ) $(UBIQX_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ) +SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ) LOG2PCAP_OBJ = utils/log2pcaphex.o LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \ - $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) + $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) lib/dummyroot.o -SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \ - $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) \ +SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ + $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \ $(PASSDB_GET_SET_OBJ) $(LIBMSRPC_OBJ) $(SECRETS_OBJ) \ $(POPT_LIB_OBJ) $(DCUTIL_OBJ) $(LIBADS_OBJ) -SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ +SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ $(PARAM_OBJ) \ - $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \ + $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \ $(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) -TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_OBJ) $(UBIQX_OBJ) +TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) RPCTORTURE_OBJ = torture/rpctorture.o \ rpcclient/display.o \ @@ -578,13 +582,13 @@ RPCTORTURE_OBJ = torture/rpctorture.o \ rpcclient/cmd_samr.o \ rpcclient/cmd_srvsvc.o \ rpcclient/cmd_netlogon.o \ - $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ) \ + $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \ $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) DEBUG2HTML_OBJ = utils/debug2html.o ubiqx/debugparse.o SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ - $(UBIQX_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ) + $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) PROTO_OBJ = $(SMBD_OBJ_MAIN) \ $(SMBD_OBJ_SRV) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \ @@ -602,7 +606,7 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \ $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o libsmb/passchange.o WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) \ - $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ) + $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ) WINBIND_WINS_NSS_PICOBJS = $(WINBIND_WINS_NSS_OBJ:.o=.@PICSUFFIX@) @@ -611,7 +615,7 @@ LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@) PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \ pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \ - lib/dummyroot.o $(PARAM_OBJ) $(LIB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ + lib/dummyroot.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ $(SECRETS_OBJ) $(UBIQX_OBJ) $(SMBLDAP_OBJ) $(LIBSAMBA_OBJ) PAM_SMBPASS_PICOOBJ = $(PAM_SMBPASS_OBJ_0:.o=.@PICSUFFIX@) @@ -636,13 +640,13 @@ WINBINDD_OBJ1 = \ WINBINDD_OBJ = \ $(WINBINDD_OBJ1) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ - $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ + $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) \ $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \ $(PROFILE_OBJ) $(SLCACHE_OBJ) $(SMBLDAP_OBJ) \ $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \ $(DCUTIL_OBJ) $(IDMAP_OBJ) lib/dummyroot.o -WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \ +WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ $(UBIQX_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) WINBIND_NSS_OBJ = nsswitch/wb_common.o lib/replace1.o @WINBIND_NSS_EXTRA_OBJS@ @@ -1190,10 +1194,10 @@ bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@ -bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \ +bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ $(UBIQX_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(LINK) -o $@ $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \ + @$(LINK) -o $@ $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ $(UBIQX_OBJ) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ) @@ -1284,7 +1288,7 @@ installclientlib: installdirs libsmbclient # Python extensions -PYTHON_OBJS = $(PARAM_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \ +PYTHON_OBJS = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \ $(UBIQX_OBJ) $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ $(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o diff --git a/source3/lib/dummysmbd.c b/source3/lib/dummysmbd.c new file mode 100644 index 0000000000..17bc321774 --- /dev/null +++ b/source3/lib/dummysmbd.c @@ -0,0 +1,29 @@ +/* + Unix SMB/CIFS implementation. + RPC pipe client + + Copyright (C) Gerald (Jerry) Carter 2004. + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* Stupid dummy functions required due to the horrible dependency mess + in Samba. */ + +void decrement_smbd_process_count( void ) +{ + return; +} + diff --git a/source3/lib/util.c b/source3/lib/util.c index e9ab72b2bf..61dbc2cb2a 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1340,6 +1340,14 @@ gid_t nametogid(const char *name) return (gid_t)-1; } +/******************************************************************* + legacy wrapper for smb_panic2() +********************************************************************/ +void smb_panic( const char *why ) +{ + smb_panic2( why, True ); +} + /******************************************************************* Something really nasty happened - panic ! ********************************************************************/ @@ -1348,7 +1356,7 @@ gid_t nametogid(const char *name) #include #endif -void smb_panic(const char *why) +void smb_panic2(const char *why, BOOL decrement_pid_count ) { char *cmd; int result; @@ -1371,6 +1379,10 @@ void smb_panic(const char *why) } #endif + /* only smbd needs to decrement the smbd counter in connections.tdb */ + if ( decrement_pid_count ) + decrement_smbd_process_count(); + cmd = lp_panic_action(); if (cmd && *cmd) { DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd)); diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index c51a5a2aac..47001c8b89 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -246,8 +246,8 @@ void brl_init(int read_only) { if (tdb) return; - tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), - read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644); + tdb = tdb_open_ex(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), + read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644, smbd_tdb_log); if (!tdb) { DEBUG(0,("Failed to open byte range locking database\n")); return; diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c3abd63818..42036cc70c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -283,10 +283,10 @@ BOOL locking_init(int read_only) if (tdb) return True; - tdb = tdb_open_log(lock_path("locking.tdb"), + tdb = tdb_open_ex(lock_path("locking.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), read_only?O_RDONLY:O_RDWR|O_CREAT, - 0644); + 0644, smbd_tdb_log); if (!tdb) { DEBUG(0,("ERROR: Failed to initialise locking database\n")); diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 1d8fb9b7ec..d9d946ffc8 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -46,12 +46,18 @@ static int tdbsam_debug_level = DBGC_ALL; struct tdbsam_privates { TDB_CONTEXT *passwd_tdb; - TDB_DATA key; /* retrive-once info */ const char *tdbsam_location; }; +struct pwent_list { + struct pwent_list *prev, *next; + TDB_DATA key; +}; +static struct pwent_list *tdbsam_pwent_list; + + /** * Convert old TDBSAM to the latest version. * @param pdb_tdb A pointer to the opened TDBSAM file which must be converted. @@ -222,33 +228,75 @@ static TDB_CONTEXT * tdbsam_tdbopen (const char *name, int open_flags) return pdb_tdb; } +/***************************************************************************** + Utility functions to open the tdb sam database + ****************************************************************************/ + +static void tdbsam_tdbclose ( struct tdbsam_privates *state ) +{ + if ( !state ) + return; + + if ( state->passwd_tdb ) { + tdb_close( state->passwd_tdb ); + state->passwd_tdb = NULL; + } + + return; + +} + +/**************************************************************************** + creates a list of user keys +****************************************************************************/ + +static int tdbsam_traverse_setpwent(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) +{ + const char *prefix = USERPREFIX; + int prefixlen = strlen (prefix); + struct pwent_list *ptr; + + if ( strncmp(key.dptr, prefix, prefixlen) == 0 ) { + if ( !(ptr=(struct pwent_list*)malloc(sizeof(struct pwent_list))) ) { + DEBUG(0,("tdbsam_traverse_setpwent: Failed to malloc new entry for list\n")); + + /* just return 0 and let the traversal continue */ + return 0; + } + ZERO_STRUCTP(ptr); + + /* save a copy of the key */ + + ptr->key.dptr = memdup( key.dptr, key.dsize ); + ptr->key.dsize = key.dsize; + + DLIST_ADD( tdbsam_pwent_list, ptr ); + + } + + + return 0; +} + /*************************************************************** Open the TDB passwd database for SAM account enumeration. + Save a list of user keys for iteration. ****************************************************************/ static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update) { + uint32 flags = update ? (O_RDWR|O_CREAT) : O_RDONLY; + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - /* Open tdb passwd */ - if (!(tdb_state->passwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, update?(O_RDWR|O_CREAT):O_RDONLY))) - { - DEBUG(0, ("Unable to open/create TDB passwd\n")); + if ( !(tdb_state->passwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, flags )) ) return NT_STATUS_UNSUCCESSFUL; - } - - tdb_state->key = tdb_firstkey(tdb_state->passwd_tdb); + tdb_traverse( tdb_state->passwd_tdb, tdbsam_traverse_setpwent, NULL ); + return NT_STATUS_OK; } -static void close_tdb(struct tdbsam_privates *tdb_state) -{ - if (tdb_state->passwd_tdb) { - tdb_close(tdb_state->passwd_tdb); - tdb_state->passwd_tdb = NULL; - } -} /*************************************************************** End enumeration of the TDB passwd list. @@ -257,8 +305,18 @@ static void close_tdb(struct tdbsam_privates *tdb_state) static void tdbsam_endsampwent(struct pdb_methods *my_methods) { struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - SAFE_FREE(tdb_state->key.dptr); - close_tdb(tdb_state); + struct pwent_list *ptr, *ptr_next; + + tdbsam_tdbclose( tdb_state ); + + /* clear out any remaining entries in the list */ + + for ( ptr=tdbsam_pwent_list; ptr; ptr = ptr_next ) { + ptr_next = ptr->next; + DLIST_REMOVE( tdbsam_pwent_list, ptr ); + SAFE_FREE( ptr->key.dptr); + SAFE_FREE( ptr ); + } DEBUG(7, ("endtdbpwent: closed sam database.\n")); } @@ -269,55 +327,48 @@ static void tdbsam_endsampwent(struct pdb_methods *my_methods) static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user) { - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - TDB_DATA data, old_key; - const char *prefix = USERPREFIX; - int prefixlen = strlen (prefix); - + TDB_DATA data; + struct pwent_list *pkey; - if (user==NULL) { - DEBUG(0,("pdb_get_sampwent: SAM_ACCOUNT is NULL.\n")); + if ( !user ) { + DEBUG(0,("tdbsam_getsampwent: SAM_ACCOUNT is NULL.\n")); return nt_status; } - /* skip all non-USER entries (eg. RIDs) */ - while ((tdb_state->key.dsize != 0) && (strncmp(tdb_state->key.dptr, prefix, prefixlen))) { - - old_key = tdb_state->key; - - /* increment to next in line */ - tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key); - - SAFE_FREE(old_key.dptr); - } - - /* do we have an valid iteration pointer? */ - if(tdb_state->passwd_tdb == NULL) { - DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n")); + if ( !tdbsam_pwent_list ) { + DEBUG(4,("tdbsam_getsampwent: end of list\n")); + tdbsam_tdbclose( tdb_state ); return nt_status; } + + if ( !tdb_state->passwd_tdb ) { + if ( !(tdb_state->passwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY)) ) + return nt_status; + } + + /* pull the next entry */ + + pkey = tdbsam_pwent_list; + DLIST_REMOVE( tdbsam_pwent_list, pkey ); + + data = tdb_fetch(tdb_state->passwd_tdb, pkey->key); - data = tdb_fetch(tdb_state->passwd_tdb, tdb_state->key); + SAFE_FREE( pkey->key.dptr); + SAFE_FREE( pkey); + if (!data.dptr) { - DEBUG(5,("pdb_getsampwent: database entry not found.\n")); + DEBUG(5,("pdb_getsampwent: database entry not found. Was the user deleted?\n")); return nt_status; } - /* unpack the buffer */ if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) { DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n")); - SAFE_FREE(data.dptr); - return nt_status; } - SAFE_FREE(data.dptr); - old_key = tdb_state->key; + SAFE_FREE( data.dptr ); - /* increment to next in line */ - tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key); - - SAFE_FREE(old_key.dptr); return NT_STATUS_OK; } @@ -335,12 +386,11 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT fstring keystr; fstring name; - if (user==NULL) { + if ( !user ) { DEBUG(0,("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n")); return nt_status; } - /* Data is stored in all lower-case */ fstrcpy(name, sname); strlower_m(name); @@ -358,7 +408,7 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT * TDB file doesn't exist, so try to create new one. This is useful to avoid * confusing error msg when adding user account first time */ - if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_CREAT, 0600))) { + if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_CREAT ))) { DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) did not exist. File successfully created.\n", tdb_state->tdbsam_location)); } else { @@ -637,7 +687,7 @@ static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCO static void free_private_data(void **vp) { struct tdbsam_privates **tdb_state = (struct tdbsam_privates **)vp; - close_tdb(*tdb_state); + tdbsam_tdbclose(*tdb_state); *tdb_state = NULL; /* No need to free any further, as it is talloc()ed */ diff --git a/source3/printing/printing_db.c b/source3/printing/printing_db.c index 0e0fb1b51d..d402aa366f 100644 --- a/source3/printing/printing_db.c +++ b/source3/printing/printing_db.c @@ -96,7 +96,8 @@ struct tdb_print_db *get_print_db_byname(const char *printername) done_become_root = True; } - p->tdb = tdb_open_log(printdb_path, 5000, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + p->tdb = tdb_open_ex(printdb_path, 5000, TDB_DEFAULT, O_RDWR|O_CREAT, + 0600, smbd_tdb_log); if (done_become_root) unbecome_root(); diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c index 5bb76eb3bd..a9ab142461 100644 --- a/source3/smbd/connection.c +++ b/source3/smbd/connection.c @@ -29,8 +29,8 @@ static TDB_CONTEXT *tdb; TDB_CONTEXT *conn_tdb_ctx(void) { if (!tdb) - tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, - O_RDWR | O_CREAT, 0644); + tdb = tdb_open_ex(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, + O_RDWR | O_CREAT, 0644, smbd_tdb_log); return tdb; } @@ -131,8 +131,8 @@ BOOL claim_connection(connection_struct *conn, const char *name,int max_connecti TDB_DATA kbuf, dbuf; if (!tdb) - tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, - O_RDWR | O_CREAT, 0644); + tdb = tdb_open_ex(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, + O_RDWR | O_CREAT, 0644, smbd_tdb_log); if (!tdb) return False; diff --git a/source3/smbd/server.c b/source3/smbd/server.c index e2ffe8cc9f..be59e92cd7 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -501,6 +501,7 @@ BOOL reload_services(BOOL test) return(ret); } + #if DUMP_CORE /******************************************************************* prepare to dump a core file - carefully! @@ -890,3 +891,4 @@ void build_options(BOOL screen); exit_server("normal exit"); return(0); } + diff --git a/source3/smbd/session.c b/source3/smbd/session.c index 4d8826d332..a811a6e305 100644 --- a/source3/smbd/session.c +++ b/source3/smbd/session.c @@ -53,8 +53,8 @@ BOOL session_claim(user_struct *vuser) } if (!tdb) { - tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, - O_RDWR | O_CREAT, 0644); + tdb = tdb_open_ex(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, + O_RDWR | O_CREAT, 0644, smbd_tdb_log); if (!tdb) { DEBUG(1,("session_claim: failed to open sessionid tdb\n")); return False; diff --git a/source3/smbd/tdbutil.c b/source3/smbd/tdbutil.c new file mode 100644 index 0000000000..cafcde2037 --- /dev/null +++ b/source3/smbd/tdbutil.c @@ -0,0 +1,85 @@ +/* + Unix SMB/CIFS implementation. + Main SMB server routines + Copyright (C) Jeremy Allison 2003 + Copyright (C) Gerald (Jerry) Carter 2004 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + +/********************************************************************** + logging function used by smbd to detect and remove corrupted tdb's +**********************************************************************/ + +void smbd_tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) +{ + va_list ap; + char *ptr = NULL; + BOOL decrement_smbd_count; + + va_start(ap, format); + vasprintf(&ptr, format, ap); + va_end(ap); + + if (!ptr || !*ptr) + return; + + DEBUG(level, ("tdb(%s): %s", tdb->name ? tdb->name : "unnamed", ptr)); + + if (tdb->ecode == TDB_ERR_CORRUPT) { + int ret; + + DEBUG(0,("tdb_log: TDB %s is corrupt. Removing file and stopping this process.\n", + tdb->name )); + + become_root(); + ret = unlink(tdb->name); + if ( ret ) { + DEBUG(0,("ERROR: %s\n", strerror(errno))); + } + unbecome_root(); + + + /* if its not connections.tdb, then make sure we decrement the + smbd count. If connections.tdb is bad, there's nothing we + can do and everything will eventually shut down or clean + up anyways */ + + if ( strcmp(tdb->name, lock_path("connections.tdb")) == 0 ) + decrement_smbd_count = False; + else + decrement_smbd_count = True; + + /* now die */ + + smb_panic2("corrupt tdb\n", decrement_smbd_count ); + } + + if (tdb->ecode == TDB_ERR_IO) + { + if ( strcmp(tdb->name, lock_path("connections.tdb")) == 0 ) + decrement_smbd_count = False; + else + decrement_smbd_count = True; + + smb_panic2( "i/o error on tdb.\n", decrement_smbd_count ); + } + + SAFE_FREE(ptr); +} + -- cgit From 8437fd40bee34353ee7fe080b9d94d20eb3d6ee6 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 12 Feb 2004 15:21:28 +0000 Subject: Start of merging changes with SAMBA_3_0. Fix up some comments so that they line up. Also change lockout_time to bad_password_time, since this is actually what is replicated. (This used to be commit adfc160082e5d1f20085e68eaacffea3fd277f1d) --- source3/passdb/passdb.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index d0a1711f0f..603b4d71d2 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -79,7 +79,7 @@ void pdb_fill_default_sam(SAM_ACCOUNT *user) user->private.logoff_time = user->private.kickoff_time = user->private.pass_must_change_time = get_time_t_max(); - user->private.fields_present = 0x00ffffff; /* don't know */ + user->private.fields_present = 0x00ffffff; user->private.logon_divs = 168; /* hours per week */ user->private.hours_len = 21; /* 21 times 8 bits = 168 */ memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */ @@ -128,7 +128,7 @@ static void destroy_pdb_talloc(SAM_ACCOUNT **user) /********************************************************************** - Alloc memory and initialises a struct sam_passwd on supplied mem_ctx. + Allocates memory and initialises a struct sam_passwd on supplied mem_ctx. ***********************************************************************/ NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user) @@ -475,10 +475,10 @@ char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length) { static fstring acct_str; - SMB_ASSERT(length <= sizeof(acct_str)); - size_t i = 0; + SMB_ASSERT(length <= sizeof(acct_str)); + acct_str[i++] = '['; if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N'; @@ -1742,7 +1742,7 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) uint32 logon_time, logoff_time, kickoff_time, - lockout_time, + bad_password_time, pass_last_set_time, pass_can_change_time, pass_must_change_time; @@ -1782,7 +1782,7 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) &logon_time, &logoff_time, &kickoff_time, - &lockout_time, + &bad_password_time, &pass_last_set_time, &pass_can_change_time, &pass_must_change_time, @@ -1919,7 +1919,7 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si uint32 logon_time, logoff_time, kickoff_time, - lockout_time, + bad_password_time, pass_last_set_time, pass_can_change_time, pass_must_change_time; @@ -1960,7 +1960,7 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si logon_time = (uint32)pdb_get_logon_time(sampass); logoff_time = (uint32)pdb_get_logoff_time(sampass); kickoff_time = (uint32)pdb_get_kickoff_time(sampass); - lockout_time = (uint32)0; + bad_password_time = (uint32)0; pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass); pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass); pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass); @@ -2066,7 +2066,7 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si logon_time, logoff_time, kickoff_time, - lockout_time, + bad_password_time, pass_last_set_time, pass_can_change_time, pass_must_change_time, @@ -2110,7 +2110,7 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si logon_time, logoff_time, kickoff_time, - lockout_time, + bad_password_time, pass_last_set_time, pass_can_change_time, pass_must_change_time, -- cgit From 595bec7bc9bb469d1209368aa5c04713fc9f4b6f Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 12 Feb 2004 16:10:35 +0000 Subject: More sync between HEAD and SAMBA_3_0 - passdb.h: replace UNKNOWN_3 with FIELDS_PRESENT - parse_samr.c: put comment back in...seems like we shouldn't lose info like this (This used to be commit 6b9efd2f4cd5cf042e2a04a08719a9fe83d54116) --- source3/include/passdb.h | 2 +- source3/rpc_parse/parse_samr.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/source3/include/passdb.h b/source3/include/passdb.h index add286816c..139a753e8b 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -92,7 +92,7 @@ enum pdb_elements { PDB_UNKNOWNSTR, PDB_MUNGEDDIAL, PDB_HOURS, - PDB_UNKNOWN3, + PDB_FIELDS_PRESENT, PDB_BAD_PASSWORD_COUNT, PDB_LOGON_COUNT, PDB_UNKNOWN6, diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 7b2d886deb..d6f371d471 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -5994,6 +5994,15 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * usr->group_rid = group_rid; usr->acb_info = pdb_get_acct_ctrl(pw); + /* + Look at a user on a real NT4 PDC with usrmgr, press + 'ok'. Then you will see that fields_present is set to + 0x08f827fa. Look at the user immediately after that again, + and you will see that 0x00fffff is returned. This solves + the problem that you get access denied after having looked + at the user. + -- Volker + */ usr->fields_present = pdb_build_fields_present(pw); usr->logon_divs = pdb_get_logon_divs(pw); -- cgit From 8733c1b8d392c4f60a1f419a60d3a68fb01db0ee Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 12 Feb 2004 16:11:43 +0000 Subject: A couple of versioning adjustments. Remove unused version #define, and define the INFO/version string in _only_ one place. (This used to be commit 02181f77897d87989341e3f18dbf0cc3e9c22991) --- source3/passdb/pdb_tdb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index d9d946ffc8..2460c97a1b 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -38,7 +38,7 @@ static int tdbsam_debug_level = DBGC_ALL; #endif #define TDBSAM_VERSION 1 /* Most recent TDBSAM version */ -#define PDB_VERSION "20010830" +#define TDBSAM_VERSION_STRING "INFO/version" #define PASSDB_FILE_NAME "passdb.tdb" #define USERPREFIX "USER_" #define RIDPREFIX "RID_" @@ -68,7 +68,7 @@ static struct pwent_list *tdbsam_pwent_list; static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from) { - const char * vstring = "INFO/version"; + const char * vstring = TDBSAM_VERSION_STRING; SAM_ACCOUNT *user = NULL; const char *prefix = USERPREFIX; TDB_DATA data, key, old_key; @@ -187,7 +187,8 @@ static TDB_CONTEXT * tdbsam_tdbopen (const char *name, int open_flags) return NULL; /* Check the version */ - version = (tdbsamver_t) tdb_fetch_int32(pdb_tdb, "INFO/version"); + version = (tdbsamver_t) tdb_fetch_int32(pdb_tdb, + TDBSAM_VERSION_STRING); if (version == -1) version = 0; /* Version not found, assume version 0 */ -- cgit From 45fd0e4dd0ff4b64cd343c8691580f5b983825ab Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 12 Feb 2004 16:13:57 +0000 Subject: Fix typo: fileds -> fields (This used to be commit 994b71487868a62054ed24c5ea5d2729c99ba8be) --- source3/rpcclient/cmd_samr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 455e5a89fc..ed06a5a4a0 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -83,7 +83,7 @@ static void display_sam_user_info_21(SAM_USER_INFO_21 *usr) printf("\tgroup_rid:\t0x%x\n" , usr->group_rid); /* Group ID */ printf("\tacb_info :\t0x%04x\n", usr->acb_info ); /* Account Control Info */ - printf("\tfileds_present:\t0x%08x\n", usr->fields_present); /* 0x00ff ffff */ + printf("\tfields_present:\t0x%08x\n", usr->fields_present); /* 0x00ff ffff */ printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */ printf("\tbad_password_count:\t0x%08x\n", usr->bad_password_count); printf("\tlogon_count:\t0x%08x\n", usr->logon_count); -- cgit From 4bfc270e088b8b17f27a162cdcafe9848e54ada0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 12 Feb 2004 17:12:06 +0000 Subject: merges from 3.0 (This used to be commit 2478501d402a07248d6181d4c9de253b203ff67c) --- source3/passdb/pdb_interface.c | 4 ++-- source3/utils/pdbedit.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 8c93aaae1e..91f790711e 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -824,7 +824,7 @@ BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) been allowed by the ACB_PWNOTREQ bit */ lm_pw = pdb_get_lanman_passwd( sam_acct ); - nt_pw = pdb_get_lanman_passwd( sam_acct ); + nt_pw = pdb_get_nt_passwd( sam_acct ); acb_flags = pdb_get_acct_ctrl( sam_acct ); if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) { acb_flags |= ACB_DISABLED; @@ -849,7 +849,7 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct) been allowed by the ACB_PWNOTREQ bit */ lm_pw = pdb_get_lanman_passwd( sam_acct ); - nt_pw = pdb_get_lanman_passwd( sam_acct ); + nt_pw = pdb_get_nt_passwd( sam_acct ); acb_flags = pdb_get_acct_ctrl( sam_acct ); if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) { acb_flags |= ACB_DISABLED; diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index f402567b74..83663c52b6 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -251,13 +251,15 @@ static int fix_users_list (struct pdb_context *in) if (!(NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent)))) return 1; while (check && (ret = NT_STATUS_IS_OK(in->pdb_getsampwent (in, sam_pwent)))) { + printf("Updating record for user %s\n", pdb_get_username(sam_pwent)); + if (!pdb_update_sam_account(sam_pwent)) { - DEBUG(0, ("Update of user %s failed!\n", pdb_get_username(sam_pwent))); + printf("Update of user %s failed!\n", pdb_get_username(sam_pwent)); } pdb_free_sam(&sam_pwent); check = NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent)); if (!check) { - DEBUG(0, ("Failed to initialise new SAM_ACCOUNT structure (out of memory?)\n")); + fprintf(stderr, "Failed to initialise new SAM_ACCOUNT structure (out of memory?)\n"); } } -- cgit From 9eb5c835f1ba71fb458ea057cc3c79330f69184b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 12 Feb 2004 17:52:15 +0000 Subject: abartlet's pdb_set/changed flag fix for NULL passwords (This used to be commit 3b373cd15d17ab495f86c8b3b219d965b5aff606) --- source3/passdb/pdb_interface.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 91f790711e..5b97c5fbad 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -61,13 +61,13 @@ static void pdb_force_pw_initialization(SAM_ACCOUNT *pass) { lm_pwd = pdb_get_lanman_passwd(pass); if (lm_pwd) - pdb_set_lanman_passwd(pass, NULL, PDB_SET); + pdb_set_lanman_passwd(pass, NULL, PDB_CHANGED); } if (pdb_get_init_flags(pass, PDB_NTPASSWD) != PDB_DEFAULT) { nt_pwd = pdb_get_nt_passwd(pass); if (nt_pwd) - pdb_set_nt_passwd(pass, NULL, PDB_SET); + pdb_set_nt_passwd(pass, NULL, PDB_CHANGED); } } @@ -828,8 +828,7 @@ BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) acb_flags = pdb_get_acct_ctrl( sam_acct ); if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) { acb_flags |= ACB_DISABLED; - pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_SET ); - pdb_set_init_flags(sam_acct, PDB_ACCTCTRL, PDB_SET); + pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_CHANGED ); } return NT_STATUS_IS_OK(pdb_context->pdb_add_sam_account(pdb_context, sam_acct)); @@ -853,8 +852,7 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct) acb_flags = pdb_get_acct_ctrl( sam_acct ); if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) { acb_flags |= ACB_DISABLED; - pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_SET ); - pdb_set_init_flags(sam_acct, PDB_ACCTCTRL, PDB_SET); + pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_CHANGED ); } return NT_STATUS_IS_OK(pdb_context->pdb_update_sam_account(pdb_context, sam_acct)); -- cgit From 5abd317a4ce3c4a033d714da74d09bbba5b80b24 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 12 Feb 2004 19:10:09 +0000 Subject: Fix format error for generating SELECT, since unknown_3 is now gone (This used to be commit 57314e060552523338071442e111fb4f7a2e1df8) --- source3/passdb/pdb_sql.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/pdb_sql.c b/source3/passdb/pdb_sql.c index d3e8b90a85..ffb8313a97 100644 --- a/source3/passdb/pdb_sql.c +++ b/source3/passdb/pdb_sql.c @@ -204,7 +204,7 @@ char *sql_account_query_select(const char *data, BOOL update, enum sql_search_fi } asprintf(&query, - "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s WHERE %s = '%s'", + "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s WHERE %s = '%s'", config_value_read(data, "logon time column", CONFIG_LOGON_TIME_DEFAULT), config_value_read(data, "logoff time column", -- cgit From b60ba1de77a5bb012117e78e57188b12f1bd25f0 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 12 Feb 2004 20:45:12 +0000 Subject: merge old change from 2.2 branch to give legend in heading (This used to be commit 1b7ba358b6c708bdede117c0cd16a7c4f7c0106a) --- source3/script/findsmb.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source3/script/findsmb.in b/source3/script/findsmb.in index fb06018fe5..546cf8ce7b 100755 --- a/source3/script/findsmb.in +++ b/source3/script/findsmb.in @@ -57,8 +57,9 @@ open(NMBLOOKUP,"$SAMBABIN/nmblookup $BCAST '*' --debuglevel=0|") || @ipaddrs = sort ipsort grep(s/ \*<00>.*$//,); # print header info - -print "\nIP ADDR NETBIOS NAME WORKGROUP/OS/VERSION $BCAST\n"; +print "\n *=DMB\n"; +print " +=LMB\n"; +print "IP ADDR NETBIOS NAME WORKGROUP/OS/VERSION $BCAST\n"; print "---------------------------------------------------------------------\n"; foreach $ip (@ipaddrs) # loop through each IP address found -- cgit From 4c5152b8fe2637ab067111ab23753f683ad692ac Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 13 Feb 2004 14:48:57 +0000 Subject: Fix a few comments/formatting issues to make it more in line with 3.0 and reduce diff output. (This used to be commit 306c021000d36f13b3740839b62df60986e4e112) --- source3/passdb/pdb_tdb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 2460c97a1b..f54463e158 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -37,7 +37,7 @@ static int tdbsam_debug_level = DBGC_ALL; #endif -#define TDBSAM_VERSION 1 /* Most recent TDBSAM version */ +#define TDBSAM_VERSION 1 /* Most recent TDBSAM version */ #define TDBSAM_VERSION_STRING "INFO/version" #define PASSDB_FILE_NAME "passdb.tdb" #define USERPREFIX "USER_" @@ -183,8 +183,11 @@ static TDB_CONTEXT * tdbsam_tdbopen (const char *name, int open_flags) tdbsamver_t version; /* Try to open tdb passwd */ - if (!(pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, open_flags, 0600))) + if (!(pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, + open_flags, 0600))) { + DEBUG(0, ("Unable to open/create TDB passwd\n")); return NULL; + } /* Check the version */ version = (tdbsamver_t) tdb_fetch_int32(pdb_tdb, @@ -230,7 +233,7 @@ static TDB_CONTEXT * tdbsam_tdbopen (const char *name, int open_flags) } /***************************************************************************** - Utility functions to open the tdb sam database + Utility functions to close the tdb sam database ****************************************************************************/ static void tdbsam_tdbclose ( struct tdbsam_privates *state ) -- cgit From 608c737cdf45ff2b6e61de97f6f19dde8fea21d2 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 13 Feb 2004 16:55:25 +0000 Subject: Apply the multiple login stuff to smbclient ... (This used to be commit 83213742dcd61ff4d30954158a5523ee0bdd850d) --- source3/client/client.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/source3/client/client.c b/source3/client/client.c index fdc6d0d4e1..d4ad5fa1fe 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2069,6 +2069,61 @@ static BOOL list_servers(const char *wk_grp) return True; } +/**************************************************************************** + Print or set current VUID +****************************************************************************/ + +static int cmd_vuid(void) +{ + fstring buf; + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("Current VUID is %d\n", cli->vuid); + return 0; + } + + cli->vuid = atoi(buf); + return 0; +} + +/**************************************************************************** + Setup a new VUID, by issuing a session setup +****************************************************************************/ + +static int cmd_logon(void) +{ + pstring l_username, l_password; + fstring buf,buf2; + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("logon []\n"); + return 0; + } + + pstrcpy(l_username, buf); + + if (!next_token_nr(NULL,buf2,NULL,sizeof(buf))) { + char *pass = getpass("Password: "); + if (pass) { + pstrcpy(l_password, pass); + got_pass = 1; + } + } else { + pstrcpy(l_password, buf2); + } + + if (!cli_session_setup(cli, l_username, + l_password, strlen(l_password), + l_password, strlen(l_password), + lp_workgroup())) { + d_printf("session setup failed: %s\n", cli_errstr(cli)); + return -1; + } + + d_printf("Current VUID is %d\n", cli->vuid); + return 0; +} + /* Some constants for completing filename arguments */ #define COMPL_NONE 0 /* No completions */ @@ -2134,6 +2189,8 @@ static struct {"tar",cmd_tar,"tar [IXFqbgNan] current directory to/from ",{COMPL_NONE,COMPL_NONE}}, {"tarmode",cmd_tarmode," tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}}, {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}}, + {"vuid",cmd_vuid,"change current vuid",{COMPL_NONE,COMPL_NONE}}, + {"logon",cmd_logon,"establish new logon",{COMPL_NONE,COMPL_NONE}}, /* Yes, this must be here, see crh's comment above. */ {"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}}, @@ -2615,7 +2672,6 @@ static struct cli_state *do_connect(const char *server, const char *share) DEBUG(1,("OS=[%s] Server=[%s]\n", c->server_os,c->server_type)); } - DEBUG(4,(" session setup ok\n")); if (!cli_send_tconX(c, sharename, "?????", -- cgit From 8b9cdc96b4886e415eccf0a8aa57adff637570fe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Feb 2004 19:05:27 +0000 Subject: Fixup the 'multiple-vuids' bugs. Jeremy. (This used to be commit a7d4a6d1167f7657113148cdf68ea3c491b51b14) --- source3/include/smb.h | 29 +++++++++++------ source3/smbd/conn.c | 10 ++++-- source3/smbd/service.c | 84 ++--------------------------------------------- source3/smbd/uid.c | 88 +++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 105 insertions(+), 106 deletions(-) diff --git a/source3/include/smb.h b/source3/include/smb.h index 7ffbe8f720..342c010124 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -423,7 +423,8 @@ typedef struct files_struct #include "sysquotas.h" /* used to hold an arbitrary blob of data */ -typedef struct data_blob { +typedef struct data_blob +{ uint8 *data; size_t length; void (*free)(struct data_blob *data_blob); @@ -436,19 +437,27 @@ typedef struct data_blob { typedef struct { - time_t modify_time; - time_t status_time; + time_t modify_time; + time_t status_time; } dir_status_struct; -struct vuid_cache { - unsigned int entries; - uint16 list[VUID_CACHE_SIZE]; +struct vuid_cache_entry +{ + uint16 vuid; + BOOL read_only; + BOOL admin_user; +}; + +struct vuid_cache +{ + unsigned int entries; + struct vuid_cache_entry array[VUID_CACHE_SIZE]; }; typedef struct { - char *name; - BOOL is_wild; + char *name; + BOOL is_wild; } name_compare_entry; /* Include VFS stuff */ @@ -468,8 +477,8 @@ typedef struct connection_struct void *dirptr; BOOL printer; BOOL ipc; - BOOL read_only; - BOOL admin_user; + BOOL read_only; /* Attributes for the current user of the share. */ + BOOL admin_user; /* Attributes for the current user of the share. */ char *dirpath; char *connectpath; char *origpath; diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 289b7d611d..9bac0acdb9 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -199,8 +199,9 @@ BOOL conn_idle_all(time_t t, int deadtime) } /**************************************************************************** -clear a vuid out of the validity cache, and as the 'owner' of a connection. + Clear a vuid out of the validity cache, and as the 'owner' of a connection. ****************************************************************************/ + void conn_clear_vuid_cache(uint16 vuid) { connection_struct *conn; @@ -212,8 +213,11 @@ void conn_clear_vuid_cache(uint16 vuid) } for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) { - if (conn->vuid_cache.list[i] == vuid) { - conn->vuid_cache.list[i] = UID_FIELD_INVALID; + if (conn->vuid_cache.array[i].vuid == vuid) { + struct vuid_cache_entry *ent = &conn->vuid_cache.array[i]; + ent->vuid = UID_FIELD_INVALID; + ent->read_only = False; + ent->admin_user = False; } } } diff --git a/source3/smbd/service.c b/source3/smbd/service.c index e5655bd9f4..78b610ae37 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -259,78 +259,6 @@ static NTSTATUS share_sanity_checks(int snum, fstring dev) return NT_STATUS_OK; } -/**************************************************************************** - readonly share? -****************************************************************************/ - -static void set_read_only(connection_struct *conn, gid_t *groups, size_t n_groups) -{ - char **list; - const char *service = lp_servicename(conn->service); - conn->read_only = lp_readonly(conn->service); - - if (!service) - return; - - str_list_copy(&list, lp_readlist(conn->service)); - if (list) { - if (!str_list_sub_basic(list, current_user_info.smb_name) ) { - DEBUG(0, ("ERROR: read list substitution failed\n")); - } - if (!str_list_substitute(list, "%S", service)) { - DEBUG(0, ("ERROR: read list service substitution failed\n")); - } - if (user_in_list(conn->user, (const char **)list, groups, n_groups)) - conn->read_only = True; - str_list_free(&list); - } - - str_list_copy(&list, lp_writelist(conn->service)); - if (list) { - if (!str_list_sub_basic(list, current_user_info.smb_name) ) { - DEBUG(0, ("ERROR: write list substitution failed\n")); - } - if (!str_list_substitute(list, "%S", service)) { - DEBUG(0, ("ERROR: write list service substitution failed\n")); - } - if (user_in_list(conn->user, (const char **)list, groups, n_groups)) - conn->read_only = False; - str_list_free(&list); - } -} - -/**************************************************************************** - admin user check -****************************************************************************/ - -static void set_admin_user(connection_struct *conn, gid_t *groups, size_t n_groups) -{ - /* admin user check */ - - /* JRA - original code denied admin user if the share was - marked read_only. Changed as I don't think this is needed, - but old code left in case there is a problem here. - */ - if (user_in_list(conn->user,lp_admin_users(conn->service), groups, n_groups) -#if 0 - && !conn->read_only -#endif - ) { - conn->admin_user = True; - conn->force_user = True; /* Admin users are effectivly 'forced' */ - DEBUG(0,("%s logged in as admin user (root privileges)\n",conn->user)); - } else { - conn->admin_user = False; - } - -#if 0 /* This done later, for now */ - /* admin users always run as uid=0 */ - if (conn->admin_user) { - conn->uid = 0; - } -#endif -} - /**************************************************************************** Make a connection, given the snum to connect to, and the vuser of the connecting user if appropriate. @@ -443,10 +371,9 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, string_set(&conn->dirpath,""); string_set(&conn->user,user); conn->nt_user_token = NULL; - - set_read_only(conn, vuser ? vuser->groups : NULL, vuser ? vuser->n_groups : 0); - - set_admin_user(conn, vuser ? vuser->groups : NULL, vuser ? vuser->n_groups : 0); + + conn->read_only = lp_readonly(conn->service); + conn->admin_user = False; /* * If force user is true, then store the @@ -478,11 +405,6 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, } } - /* admin users always run as uid=0 */ - if (conn->admin_user) { - conn->uid = 0; - } - #ifdef HAVE_GETGRNAM /* * If force group is true, then override diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index f3d9004dd9..3859298055 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -54,33 +54,97 @@ BOOL change_to_guest(void) return True; } +/**************************************************************************** + Readonly share for this user ? +****************************************************************************/ + +static BOOL is_share_read_only_for_user(connection_struct *conn, user_struct *vuser) +{ + char **list; + const char *service = lp_servicename(conn->service); + BOOL read_only_ret = lp_readonly(conn->service); + + if (!service) + return read_only_ret; + + str_list_copy(&list, lp_readlist(conn->service)); + if (list) { + if (!str_list_sub_basic(list, vuser->user.smb_name) ) { + DEBUG(0, ("is_share_read_only_for_user: ERROR: read list substitution failed\n")); + } + if (!str_list_substitute(list, "%S", service)) { + DEBUG(0, ("is_share_read_only_for_user: ERROR: read list service substitution failed\n")); + } + if (user_in_list(vuser->user.unix_name, (const char **)list, vuser->groups, vuser->n_groups)) { + read_only_ret = True; + } + str_list_free(&list); + } + + str_list_copy(&list, lp_writelist(conn->service)); + if (list) { + if (!str_list_sub_basic(list, vuser->user.smb_name) ) { + DEBUG(0, ("is_share_read_only_for_user: ERROR: write list substitution failed\n")); + } + if (!str_list_substitute(list, "%S", service)) { + DEBUG(0, ("is_share_read_only_for_user: ERROR: write list service substitution failed\n")); + } + if (user_in_list(vuser->user.unix_name, (const char **)list, vuser->groups, vuser->n_groups)) { + read_only_ret = False; + } + str_list_free(&list); + } + + DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user %s\n", + service, read_only_ret ? "read-only" : "read-write", vuser->user.unix_name )); + + return read_only_ret; +} + /******************************************************************* Check if a username is OK. ********************************************************************/ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { - unsigned i; - for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) - if (conn->vuid_cache.list[i] == vuser->vuid) + unsigned int i; + struct vuid_cache_entry *ent = NULL; + BOOL readonly_share; + + for (i=0;ivuid_cache.entries && i< VUID_CACHE_SIZE;i++) { + if (conn->vuid_cache.array[i].vuid == vuser->vuid) { + ent = &conn->vuid_cache.array[i]; + conn->read_only = ent->read_only; + conn->admin_user = ent->admin_user; return(True); - - if ((conn->force_user || conn->force_group) - && (conn->vuid != vuser->vuid)) { - return False; + } } - + if (!user_ok(vuser->user.unix_name,snum, vuser->groups, vuser->n_groups)) return(False); - if (!share_access_check(conn, snum, vuser, conn->read_only ? FILE_READ_DATA : FILE_WRITE_DATA)) { + readonly_share = is_share_read_only_for_user(conn, vuser); + + if (!share_access_check(conn, snum, vuser, readonly_share ? FILE_READ_DATA : FILE_WRITE_DATA)) { return False; } i = conn->vuid_cache.entries % VUID_CACHE_SIZE; - conn->vuid_cache.list[i] = vuser->vuid; + if (conn->vuid_cache.entries < VUID_CACHE_SIZE) + conn->vuid_cache.entries++; + + ent = &conn->vuid_cache.array[i]; + ent->vuid = vuser->vuid; + ent->read_only = readonly_share; + + if (user_in_list(vuser->user.unix_name ,lp_admin_users(conn->service), vuser->groups, vuser->n_groups)) { + ent->admin_user = True; + } else { + ent->admin_user = False; + } - conn->vuid_cache.entries++; + conn->read_only = ent->read_only; + conn->admin_user = ent->admin_user; return(True); } @@ -132,7 +196,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) current_user.ngroups = conn->ngroups; token = conn->nt_user_token; } else if ((vuser) && check_user_ok(conn, vuser, snum)) { - uid = vuser->uid; + uid = conn->admin_user ? 0 : vuser->uid; gid = vuser->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; -- cgit From 94cb77579b3c4834f11265ce0f3cb70f474181a8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Feb 2004 22:06:23 +0000 Subject: Added Andrew Bartlett's patch to use an allocated buffer for count_chars. Jeremy. (This used to be commit 4ec9e330787cbc01849a91573f760f639b28be7e) --- source3/lib/util_str.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 2d1f596c97..cde6b2e7a1 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -557,10 +557,16 @@ size_t count_chars(const char *s,char c) { smb_ucs2_t *ptr; int count; - push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE); - for(count=0,ptr=tmpbuf;*ptr;ptr++) + smb_ucs2_t *alloc_tmpbuf; + + if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) { + return 0; + } + + for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++) if(*ptr==UCS2_CHAR(c)) count++; + return(count); } -- cgit From 3122f76d3db28b123459f5966f4ef03b56b16642 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 13 Feb 2004 22:10:12 +0000 Subject: Fix eta calculation when resuming (This used to be commit c4114a0664467383fc343a55360b48a985fa45ac) --- source3/utils/smbget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c index 92a3831752..ab6e368c70 100644 --- a/source3/utils/smbget.c +++ b/source3/utils/smbget.c @@ -219,7 +219,7 @@ void print_progress(const char *name, time_t start, time_t now, off_t start_pos, char *status, *filename; int len; if(now - start)avg = 1.0 * (pos - start_pos) / (now - start); - eta = (total - pos - start_pos) / avg; + eta = (total - pos) / avg; if(total)prcnt = 100.0 * pos / total; human_readable(pos, hpos, sizeof(hpos)); -- cgit From 78c2b8fe472e1436d231bf32a0f2622993bfb136 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Feb 2004 22:35:02 +0000 Subject: Typo (missed SAFE_FREE)., Jeremy. (This used to be commit dd014ab358e861f3828cb34c09c5800606c8da59) --- source3/lib/util_str.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index cde6b2e7a1..71c8d56e40 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -557,7 +557,7 @@ size_t count_chars(const char *s,char c) { smb_ucs2_t *ptr; int count; - smb_ucs2_t *alloc_tmpbuf; + smb_ucs2_t *alloc_tmpbuf = NULL; if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) { return 0; @@ -567,6 +567,7 @@ size_t count_chars(const char *s,char c) if(*ptr==UCS2_CHAR(c)) count++; + SAFE_FREE(alloc_tmpbuf); return(count); } -- cgit From dc0e22109d8a5dec1d5f65816d288a6561170f70 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sat, 14 Feb 2004 14:23:51 +0000 Subject: Sync with openldap schema. Add munged dial and config attrs/ocs. (This used to be commit 3f8824f7d02bcf46445360542df686a7a75ab52d) --- examples/LDAP/samba.schema.at.IBM-DS | 13 +++++++++++++ examples/LDAP/samba.schema.oc.IBM-DS | 6 +++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/examples/LDAP/samba.schema.at.IBM-DS b/examples/LDAP/samba.schema.at.IBM-DS index 5aa70b5101..bc39d520fb 100644 --- a/examples/LDAP/samba.schema.at.IBM-DS +++ b/examples/LDAP/samba.schema.at.IBM-DS @@ -44,3 +44,16 @@ attributetypes=( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' DESC 'Next NT rid t attributetypes=( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' DESC 'Base at which the samba RID generation algorithm should operate' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributetypes=( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' DESC 'Share Name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' DESC 'Option Name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' DESC 'A boolean option' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' DESC 'An integer option' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' DESC 'A string option' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption' DESC 'A string list option' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetypes=( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC '' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} ) diff --git a/examples/LDAP/samba.schema.oc.IBM-DS b/examples/LDAP/samba.schema.oc.IBM-DS index 202c332407..8f556520de 100644 --- a/examples/LDAP/samba.schema.oc.IBM-DS +++ b/examples/LDAP/samba.schema.oc.IBM-DS @@ -1,6 +1,6 @@ ## Samba 3.0 schema for IBM Directory Server 5.1 - object classes only -objectclasses=( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY DESC 'Samba 3.0 Auxilary SAM Account' MUST ( uid $ sambaSID ) MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sambaPrimaryGroupSID $ sambaDomainName )) +objectclasses=( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY DESC 'Samba 3.0 Auxilary SAM Account' MUST ( uid $ sambaSID ) MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial )) objectclasses=( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY DESC 'Samba Group Mapping' MUST ( gidNumber $ sambaSID $ sambaGroupType ) MAY ( displayName $ description )) @@ -12,4 +12,8 @@ objectclasses=( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIAR objectclasses=( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL DESC 'Structural Class for a SID' MUST ( sambaSID ) ) +objectclasses=( 1.3.6.1.4.1.7165.1.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY DESC 'Samba Configuration Section' MAY ( description ) ) +objectclasses=( 1.3.6.1.4.1.7165.1.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL DESC 'Samba Share Section' MUST ( sambaShareName ) MAY ( description ) ) + +objectclasses=( 1.3.6.1.4.1.7165.1.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL DESC 'Samba Configuration Option' MUST ( sambaOptionName ) MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringListoption $ description ) ) -- cgit From 1687d2d607039938bf18fe8d4d3300f8c33f3d28 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 16 Feb 2004 14:05:46 +0000 Subject: Fix success message for net groupmap modify Volker (This used to be commit d8ff6e4b30bda45b5f8680694da383d5769d7db5) --- source3/utils/net_groupmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/utils/net_groupmap.c b/source3/utils/net_groupmap.c index 06a8daa775..416f42507d 100644 --- a/source3/utils/net_groupmap.c +++ b/source3/utils/net_groupmap.c @@ -414,7 +414,7 @@ static int net_groupmap_modify(int argc, const char **argv) return -1; } - d_printf("Updated mapping entry for %s\n", ntgroup); + d_printf("Updated mapping entry for %s\n", map.nt_name); return 0; } -- cgit From c55fbad91087029679e4b57718d6e4e7de12656c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 16 Feb 2004 14:25:40 +0000 Subject: Cosmetic fix: use sid_is_in_our_domain. Volker (This used to be commit fc0dc0607d03eaefc2a0e3ffe7f1cf3612e73e0c) --- source3/rpc_server/srv_samr_nt.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index b8de24cf39..3c9adf4129 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3263,7 +3263,6 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_ int final_num_sids = 0; int i; DOM_SID group_sid; - uint32 group_rid; fstring group_sid_str; DOM_SID *sids=NULL; @@ -3282,17 +3281,14 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_ return r_u->status; } - /* todo: change to use sid_compare_front */ - - sid_split_rid(&group_sid, &group_rid); sid_to_string(group_sid_str, &group_sid); DEBUG(10, ("sid is %s\n", group_sid_str)); - /* can we get a query for an SID outside our domain ? */ - if (!sid_equal(&group_sid, get_global_sam_sid())) + if (!sid_check_is_in_our_domain(&group_sid)) { + DEBUG(3, ("sid %s is not in our domain\n", group_sid_str)); return NT_STATUS_NO_SUCH_GROUP; + } - sid_append_rid(&group_sid, group_rid); DEBUG(10, ("lookup on Domain SID\n")); if(!get_domain_group_from_sid(group_sid, &map)) -- cgit From 371e8bf7b490c3c9b29bdfd6b2c0d556ad391d95 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 17 Feb 2004 10:09:12 +0000 Subject: If there are no alias members, don't ask for their sids. Volker (This used to be commit 9d66043ed71d0c0f787a67b06b93f4f3b489c21c) --- source3/utils/net_rpc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index b92d7ec81e..80f02f2ae9 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1342,6 +1342,10 @@ rpc_list_alias_members(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + if (num_members == 0) { + return NT_STATUS_OK; + } + cli_nt_session_close(cli); if (!cli_nt_session_open(cli, PI_LSARPC)) { -- cgit From c3dc9f8f5a81146d753a50c022df273e5eca5de5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 17 Feb 2004 10:12:57 +0000 Subject: In samr_lookup_names Windows does not return WKN_GRP(5) but ALIAS(4) when you search in BUILTIN. Match that. Volker (This used to be commit 471cf1bf87638953bec4954667bbf8a49c693903) --- source3/rpc_server/srv_samr_nt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 3c9adf4129..c0d352483f 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -1418,7 +1418,12 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO if (sid_equal(&sid, &pol_sid)) { rid[i]=local_rid; - type[i]=local_type; + + /* Windows does not return WKN_GRP here, even + * on lookups in builtin */ + type[i] = (local_type == SID_NAME_WKN_GRP) ? + SID_NAME_ALIAS : local_type; + r_u->status = NT_STATUS_OK; } } -- cgit From f7e06fa12b4102a085c4c499dad35daaa61bbc3a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 17 Feb 2004 15:27:20 +0000 Subject: Don't try to show entries that could not be listed. Volker (This used to be commit 5fb9028942e2f16b153f42911e837008824dcecc) --- source3/utils/net_rpc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 80f02f2ae9..de6c8be900 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1131,6 +1131,9 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name, result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol, &start_idx, 3, &num_entries, max_entries, max_size, &ctr); + + if (!NT_STATUS_IS_OK(result)) + break; for (i = 0; i < num_entries; i++) { @@ -1155,6 +1158,9 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name, &start_idx, max_entries, &groups, &num_entries); + if (!NT_STATUS_IS_OK(result)) + break; + for (i = 0; i < num_entries; i++) { char *description = NULL; @@ -1206,6 +1212,9 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name, &start_idx, max_entries, &groups, &num_entries); + if (!NT_STATUS_IS_OK(result)) + break; + for (i = 0; i < num_entries; i++) { char *description = NULL; -- cgit From dfc98bd6efc023a4215081cd94209d43f20c4cbe Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 17 Feb 2004 15:56:58 +0000 Subject: Also set alias info for builtins. Volker (This used to be commit 32682cd81485e295720fc65c98669c2e6e5c6043) --- source3/rpc_server/srv_samr_nt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index c0d352483f..a087e28f09 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -4116,7 +4116,8 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_ return r_u->status; } - if (!get_local_group_from_sid(&group_sid, &map)) + if (!get_local_group_from_sid(&group_sid, &map) && + !get_builtin_group_from_sid(&group_sid, &map)) return NT_STATUS_NO_SUCH_GROUP; ctr=&q_u->ctr; -- cgit From 25d96fd0f0d3812fc05492cea56a936ff8a0452d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 17 Feb 2004 21:29:05 +0000 Subject: When creating a group via a script, don't let winbind do it as well. Volker (This used to be commit f90c590731b45e413e70cd5d9b56d0d77dd48391) --- source3/groupdb/mapping.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 048a6c5db0..71ef38e6c8 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -838,11 +838,9 @@ int smb_create_group(char *unix_group, gid_t *new_gid) close(fd); } - } - /* Try winbindd */ + } else if ( winbind_create_group( unix_group, NULL ) ) { - if ( winbind_create_group( unix_group, NULL ) ) { DEBUG(3,("smb_create_group: winbindd created the group (%s)\n", unix_group)); ret = 0; -- cgit From 9be8961cc98f59079bccaeaf98eec964741d6f1a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 17 Feb 2004 22:46:27 +0000 Subject: Fix based on Volker's code to correctly return code from lsa_lookup_sids on unmapped sids. Jeremy. (This used to be commit 0ac64c8b4d944315cf49e6b183c07396abc7bab3) --- source3/rpc_server/srv_lsa_nt.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 4a3f6ddbf1..ddf79ef564 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -252,9 +252,6 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME /* Lookup sid from winbindd */ - memset(dom_name, '\0', sizeof(dom_name)); - memset(name, '\0', sizeof(name)); - status = lookup_sid(&find_sid, dom_name, name, &sid_name_use); DEBUG(5, ("init_lsa_trans_names: %s\n", status ? "found" : @@ -262,21 +259,25 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME if (!status) { sid_name_use = SID_NAME_UNKNOWN; + memset(dom_name, '\0', sizeof(dom_name)); + sid_to_string(name, &find_sid); + dom_idx = -1; + + DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to " + "referenced list.\n", name )); } else { (*mapped_count)++; - } + /* Store domain sid in ref array */ + if (find_sid.num_auths == 5) { + sid_split_rid(&find_sid, &rid); + } + dom_idx = init_dom_ref(ref, dom_name, &find_sid); - /* Store domain sid in ref array */ + DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to " + "referenced list.\n", dom_name, name )); - if (find_sid.num_auths == 5) { - sid_split_rid(&find_sid, &rid); } - dom_idx = init_dom_ref(ref, dom_name, &find_sid); - - DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to " - "referenced list.\n", dom_name, name )); - init_lsa_trans_name(&trn->name[total], &trn->uni_name[total], sid_name_use, name, dom_idx); total++; @@ -301,11 +302,6 @@ static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, r_l->dom_ref = ref; r_l->names = names; r_l->mapped_count = mapped_count; - - if (mapped_count == 0) - r_l->status = NT_STATUS_NONE_MAPPED; - else - r_l->status = NT_STATUS_OK; } static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size) @@ -665,6 +661,12 @@ done: /* set up the LSA Lookup SIDs response */ init_lsa_trans_names(p->mem_ctx, ref, names, num_entries, sid, &mapped_count); + if (mapped_count == 0) + r_u->status = NT_STATUS_NONE_MAPPED; + else if (mapped_count != num_entries) + r_u->status = STATUS_SOME_UNMAPPED; + else + r_u->status = NT_STATUS_OK; init_reply_lookup_sids(r_u, ref, names, mapped_count); return r_u->status; -- cgit From cc5dc7cb6733c27ec763f8e660aaeb321563fa1e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Feb 2004 01:55:21 +0000 Subject: Fix the "too many fcntl locks" scalability problem raised by tridge. I've now tested this in daemon mode and also on xinetd and I'm pretty sure it's working. Jeremy. (This used to be commit f3e51dbc21c616d261f0a65b9fa69dbb8b5a9a0f) --- source3/smbd/server.c | 34 ++++++++++++++++++++-------------- source3/smbd/session.c | 29 +++++++++++++++++++---------- source3/tdb/tdb.c | 32 +++++++++++++++++++++++--------- source3/tdb/tdbutil.c | 2 -- 4 files changed, 62 insertions(+), 35 deletions(-) diff --git a/source3/smbd/server.c b/source3/smbd/server.c index be59e92cd7..1de33739b2 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -405,10 +405,10 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ done correctly in the process. */ reset_globals_after_fork(); - /* tdb needs special fork handling */ + /* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */ if (tdb_reopen_all() == -1) { DEBUG(0,("tdb_reopen_all failed.\n")); - return False; + smb_panic("tdb_reopen_all failed."); } return True; @@ -809,9 +809,27 @@ void build_options(BOOL screen); if (is_daemon) pidfile_create("smbd"); + /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */ if (!message_init()) exit(1); + if (!session_init()) + exit(1); + + if (conn_tdb_ctx() == NULL) + exit(1); + + if (!locking_init(0)) + exit(1); + + if (!share_info_db_init()) + exit(1); + + namecache_enable(); + + if (!init_registry()) + exit(1); + if (!print_backend_init()) exit(1); @@ -832,17 +850,6 @@ void build_options(BOOL screen); * everything after this point is run after the fork() */ - namecache_enable(); - - if (!locking_init(0)) - exit(1); - - if (!share_info_db_init()) - exit(1); - - if (!init_registry()) - exit(1); - /* Initialise the password backed before the global_sam_sid to ensure that we fetch from ldap before we make a domain sid up */ @@ -891,4 +898,3 @@ void build_options(BOOL screen); exit_server("normal exit"); return(0); } - diff --git a/source3/smbd/session.c b/source3/smbd/session.c index a811a6e305..61118f13dd 100644 --- a/source3/smbd/session.c +++ b/source3/smbd/session.c @@ -28,6 +28,22 @@ #include "includes.h" static TDB_CONTEXT *tdb; + +BOOL session_init(void) +{ + if (tdb) + return True; + + tdb = tdb_open_ex(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, + O_RDWR | O_CREAT, 0644, smbd_tdb_log); + if (!tdb) { + DEBUG(1,("session_init: failed to open sessionid tdb\n")); + return False; + } + + return True; +} + /* called when a session is created */ BOOL session_claim(user_struct *vuser) { @@ -52,14 +68,8 @@ BOOL session_claim(user_struct *vuser) return True; } - if (!tdb) { - tdb = tdb_open_ex(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, - O_RDWR | O_CREAT, 0644, smbd_tdb_log); - if (!tdb) { - DEBUG(1,("session_claim: failed to open sessionid tdb\n")); - return False; - } - } + if (!session_init()) + return False; ZERO_STRUCT(sessionid); @@ -190,7 +200,7 @@ void session_yield(user_struct *vuser) static BOOL session_traverse(int (*fn)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *), void *state) { - if (!tdb) { + if (!session_init()) { DEBUG(3, ("No tdb opened\n")); return False; } @@ -238,4 +248,3 @@ int list_sessions(struct sessionid **session_list) *session_list = sesslist.sessions; return sesslist.count; } - diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index 7ad39175ac..7b10cfb377 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -1705,7 +1705,7 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, { TDB_CONTEXT *tdb; struct stat st; - int rev = 0, locked; + int rev = 0, locked = 0; unsigned char *vp; u32 vertest; @@ -1763,8 +1763,8 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, } /* we need to zero database if we are the only one with it open */ - if ((locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0)) - && (tdb_flags & TDB_CLEAR_IF_FIRST)) { + if ((tdb_flags & TDB_CLEAR_IF_FIRST) && + (locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))) { open_flags |= O_CREAT; if (ftruncate(tdb->fd, 0) == -1) { TDB_LOG((tdb, 0, "tdb_open_ex: " @@ -1837,10 +1837,19 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, name, strerror(errno))); goto fail; } + } - /* leave this lock in place to indicate it's in use */ - if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) - goto fail; + + /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if + we didn't get the initial exclusive lock as we need to let all other + users know we're using it. */ + + if (tdb_flags & TDB_CLEAR_IF_FIRST) { + /* leave this lock in place to indicate it's in use */ + if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) + goto fail; + } + internal: /* Internal (memory-only) databases skip all the code above to @@ -2018,12 +2027,14 @@ void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , cons } -/* reopen a tdb - this is used after a fork to ensure that we have an independent +/* reopen a tdb - this can be used after a fork to ensure that we have an independent seek pointer from our parent and to re-establish locks */ int tdb_reopen(TDB_CONTEXT *tdb) { struct stat st; + if (tdb->flags & TDB_INTERNAL) + return 0; /* Nothing to do. */ if (tdb_munmap(tdb) != 0) { TDB_LOG((tdb, 0, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); goto fail; @@ -2044,7 +2055,7 @@ int tdb_reopen(TDB_CONTEXT *tdb) goto fail; } tdb_mmap(tdb); - if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) { + if ((tdb->flags & TDB_CLEAR_IF_FIRST) && (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)) { TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n")); goto fail; } @@ -2062,7 +2073,10 @@ int tdb_reopen_all(void) TDB_CONTEXT *tdb; for (tdb=tdbs; tdb; tdb = tdb->next) { - if (tdb_reopen(tdb) != 0) return -1; + /* Ensure no clear-if-first. */ + tdb->flags &= ~TDB_CLEAR_IF_FIRST; + if (tdb_reopen(tdb) != 0) + return -1; } return 0; diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c index bae9a8b9d4..304bf9c816 100644 --- a/source3/tdb/tdbutil.c +++ b/source3/tdb/tdbutil.c @@ -826,5 +826,3 @@ void tdb_search_list_free(TDB_LIST_NODE* node) node = next_node; }; } - - -- cgit From 6c038e463f2c76a5b1fd03d2adaf17cfd95a32b6 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 19 Feb 2004 15:45:40 +0000 Subject: reformatting (This used to be commit cd48827418d8be15470e833ea19ab9830e160e12) --- source3/smbd/lanman.c | 138 +++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index c4df84e76c..d715ab4ddc 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -1557,87 +1557,87 @@ static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,ch char **rdata,char **rparam, int *rdata_len,int *rparam_len) { - char *str1 = param+2; - char *str2 = skip_string(str1,1); - char *p = skip_string(str2,1); - int uLevel = SVAL(p,0); - fstring sharename; - fstring comment; - pstring pathname; - char *command, *cmdname; - unsigned int offset; - int snum; - int res = ERRunsup; + char *str1 = param+2; + char *str2 = skip_string(str1,1); + char *p = skip_string(str2,1); + int uLevel = SVAL(p,0); + fstring sharename; + fstring comment; + pstring pathname; + char *command, *cmdname; + unsigned int offset; + int snum; + int res = ERRunsup; - /* check it's a supported varient */ - if (!prefix_ok(str1,RAP_WShareAdd_REQ)) return False; - if (!check_share_info(uLevel,str2)) return False; - if (uLevel != 2) return False; - - pull_ascii_fstring(sharename,data); - snum = find_service(sharename); - if (snum >= 0) { /* already exists */ - res = ERRfilexists; - goto error_exit; - } + /* check it's a supported varient */ + if (!prefix_ok(str1, RAP_WShareAdd_REQ)) return False; + if (!check_share_info(uLevel, str2)) return False; + if (uLevel != 2) return False; + + pull_ascii_fstring(sharename, data); + snum = find_service(sharename); + if (snum >= 0) { /* already exists */ + res = ERRfilexists; + goto error_exit; + } - /* only support disk share adds */ - if (SVAL(data,14)!=STYPE_DISKTREE) return False; + /* only support disk share adds */ + if (SVAL(data,14) != STYPE_DISKTREE) return False; - offset = IVAL(data, 16); - if (offset >= mdrcnt) { - res = ERRinvalidparam; - goto error_exit; - } - pull_ascii_fstring(comment, offset? (data+offset) : ""); + offset = IVAL(data, 16); + if (offset >= mdrcnt) { + res = ERRinvalidparam; + goto error_exit; + } + pull_ascii_fstring(comment, offset? (data+offset) : ""); - offset = IVAL(data, 26); - if (offset >= mdrcnt) { - res = ERRinvalidparam; - goto error_exit; - } - pull_ascii_pstring(pathname, offset? (data+offset) : ""); + offset = IVAL(data, 26); + if (offset >= mdrcnt) { + res = ERRinvalidparam; + goto error_exit; + } + pull_ascii_pstring(pathname, offset? (data+offset) : ""); - string_replace(sharename, '"', ' '); - string_replace(pathname, '"', ' '); - string_replace(comment, '"', ' '); + string_replace(sharename, '"', ' '); + string_replace(pathname, '"', ' '); + string_replace(comment, '"', ' '); - cmdname = lp_add_share_cmd(); + cmdname = lp_add_share_cmd(); - if (!cmdname || *cmdname == '\0') return False; + if (!cmdname || *cmdname == '\0') return False; - asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\"", - lp_add_share_cmd(), dyn_CONFIGFILE, sharename, pathname, comment); + asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\"", + lp_add_share_cmd(), dyn_CONFIGFILE, sharename, pathname, comment); - if (command) { - DEBUG(10,("api_RNetShareAdd: Running [%s]\n", command )); - if ((res = smbrun(command, NULL)) != 0) { - DEBUG(1,("api_RNetShareAdd: Running [%s] returned (%d)\n", command, res )); - SAFE_FREE(command); - res = ERRnoaccess; - goto error_exit; - } else { - SAFE_FREE(command); - message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL); - } - } else return False; + if (command) { + DEBUG(10,("api_RNetShareAdd: Running [%s]\n", command )); + if ((res = smbrun(command, NULL)) != 0) { + DEBUG(1,("api_RNetShareAdd: Running [%s] returned (%d)\n", command, res )); + SAFE_FREE(command); + res = ERRnoaccess; + goto error_exit; + } else { + SAFE_FREE(command); + message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL); + } + } else return False; - *rparam_len = 6; - *rparam = REALLOC(*rparam,*rparam_len); - SSVAL(*rparam,0,NERR_Success); - SSVAL(*rparam,2,0); /* converter word */ - SSVAL(*rparam,4,*rdata_len); - *rdata_len = 0; + *rparam_len = 6; + *rparam = REALLOC(*rparam, *rparam_len); + SSVAL(*rparam, 0, NERR_Success); + SSVAL(*rparam, 2, 0); /* converter word */ + SSVAL(*rparam, 4, *rdata_len); + *rdata_len = 0; - return True; + return True; - error_exit: - *rparam_len = 4; - *rparam = REALLOC(*rparam,*rparam_len); - *rdata_len = 0; - SSVAL(*rparam,0,res); - SSVAL(*rparam,2,0); - return True; +error_exit: + *rparam_len = 4; + *rparam = REALLOC(*rparam, *rparam_len); + *rdata_len = 0; + SSVAL(*rparam, 0, res); + SSVAL(*rparam, 2, 0); + return True; } -- cgit From c32cfdb505d711f1496f81fe646fa42f1c29d91f Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 19 Feb 2004 15:57:54 +0000 Subject: Add bad password time fields (This used to be commit 9f496e113c60bde1746c7f1063e83735117b2fe8) --- source3/include/passdb.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 139a753e8b..6489704fdd 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -73,6 +73,7 @@ enum pdb_elements { PDB_LOGONTIME, PDB_LOGOFFTIME, PDB_KICKOFFTIME, + PDB_BAD_PASSWORD_TIME, PDB_CANCHANGETIME, PDB_MUSTCHANGETIME, PDB_PLAINTEXT_PW, @@ -150,6 +151,7 @@ typedef struct sam_passwd time_t logon_time; /* logon time */ time_t logoff_time; /* logoff time */ time_t kickoff_time; /* kickoff time */ + time_t bad_password_time; /* last bad password entered */ time_t pass_last_set_time; /* password last set time */ time_t pass_can_change_time; /* password can change time */ time_t pass_must_change_time; /* password must change time */ -- cgit From 549fe06682e3b2446543b98061a4da419d13489f Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 19 Feb 2004 15:59:30 +0000 Subject: Add functions to get/set bad password time (This used to be commit 0a2b792556b3aaa056a1fa6adb35627fdb804758) --- source3/passdb/passdb.c | 3 ++- source3/passdb/pdb_get_set.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 603b4d71d2..ddba4c6897 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1819,6 +1819,7 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) pdb_set_logon_time(sampass, logon_time, PDB_SET); pdb_set_logoff_time(sampass, logoff_time, PDB_SET); pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); + pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET); pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET); pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET); pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET); @@ -1960,7 +1961,7 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si logon_time = (uint32)pdb_get_logon_time(sampass); logoff_time = (uint32)pdb_get_logoff_time(sampass); kickoff_time = (uint32)pdb_get_kickoff_time(sampass); - bad_password_time = (uint32)0; + bad_password_time = (uint32)pdb_get_bad_password_time(sampass); pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass); pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass); pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass); diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index be03157636..3974115588 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -72,6 +72,14 @@ time_t pdb_get_kickoff_time (const SAM_ACCOUNT *sampass) return (-1); } +time_t pdb_get_bad_password_time (const SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->private.bad_password_time); + else + return (-1); +} + time_t pdb_get_pass_last_set_time (const SAM_ACCOUNT *sampass) { if (sampass) @@ -382,6 +390,17 @@ BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_s return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag); } +BOOL pdb_set_bad_password_time (SAM_ACCOUNT *sampass, time_t mytime, + enum pdb_value_state flag) +{ + if (!sampass) + return False; + + sampass->private.bad_password_time = mytime; + + return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag); +} + BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) { if (!sampass) -- cgit From 7246b47c105a6bb077ff80684a74c3a056eacc46 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 19 Feb 2004 16:00:33 +0000 Subject: Add bad password reset and display of bad password count/time (This used to be commit 22c312b31d545914ae3fd12a11915ed046421f38) --- source3/utils/pdbedit.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 83663c52b6..733a1289da 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -48,6 +48,7 @@ #define BIT_IMPORT 0x01000000 #define BIT_EXPORT 0x02000000 #define BIT_FIX_INIT 0x04000000 +#define BIT_BADPWRESET 0x08000000 #define MASK_ALWAYS_GOOD 0x0000001F #define MASK_USER_GOOD 0x00401F00 @@ -153,6 +154,11 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst tmp = pdb_get_pass_must_change_time(sam_pwent); printf ("Password must change: %s\n", tmp ? http_timestring(tmp) : "0"); + + tmp = pdb_get_bad_password_time(sam_pwent); + printf ("Last bad password : %s\n", tmp ? http_timestring(tmp) : "0"); + printf ("Bad password count : %d\n", + pdb_get_bad_password_count(sam_pwent)); } else if (smbpwdstyle) { char lm_passwd[33]; @@ -277,7 +283,8 @@ static int set_user_info (struct pdb_context *in, const char *username, const char *fullname, const char *homedir, const char *drive, const char *script, const char *profile, const char *account_control, - const char *user_sid, const char *group_sid) + const char *user_sid, const char *group_sid, + const BOOL badpw) { SAM_ACCOUNT *sam_pwent=NULL; BOOL ret; @@ -348,6 +355,11 @@ static int set_user_info (struct pdb_context *in, const char *username, } pdb_set_group_sid (sam_pwent, &g_sid, PDB_CHANGED); } + + if (badpw) { + pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED); + pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED); + } if (NT_STATUS_IS_OK(in->pdb_update_sam_account (in, sam_pwent))) print_user_info (in, username, True, False); @@ -595,6 +607,7 @@ int main (int argc, char **argv) static char *group_sid = NULL; static long int account_policy_value = 0; BOOL account_policy_value_set = False; + static BOOL badpw_reset = False; struct pdb_context *bin; struct pdb_context *bout; @@ -625,6 +638,7 @@ int main (int argc, char **argv) {"value", 'C', POPT_ARG_LONG, &account_policy_value, 'C',"set the account policy to this value", NULL}, {"account-control", 'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL}, {"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL}, + {"bad-password-count-reset", 'z', POPT_ARG_NONE, &badpw_reset, 0, "reset bad password count", NULL}, POPT_COMMON_SAMBA POPT_TABLEEND }; @@ -677,7 +691,8 @@ int main (int argc, char **argv) (account_policy ? BIT_ACCPOLICY : 0) + (account_policy_value_set ? BIT_ACCPOLVAL : 0) + (backend_in ? BIT_IMPORT : 0) + - (backend_out ? BIT_EXPORT : 0); + (backend_out ? BIT_EXPORT : 0) + + (badpw_reset ? BIT_BADPWRESET : 0); if (setparms & BIT_BACKEND) { if (!NT_STATUS_IS_OK(make_pdb_context_string(&bdef, backend))) { @@ -774,6 +789,12 @@ int main (int argc, char **argv) /* mask out users options */ checkparms &= ~MASK_USER_GOOD; + + /* if bad password count is reset, we must be modifying */ + if (checkparms & BIT_BADPWRESET) { + checkparms |= BIT_MODIFY; + checkparms &= ~BIT_BADPWRESET; + } /* account operation */ if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) { @@ -810,7 +831,8 @@ int main (int argc, char **argv) home_drive, logon_script, profile_path, account_control, - user_sid, group_sid); + user_sid, group_sid, + badpw_reset); } } -- cgit From fba14cbfbecb8eef8b030d46309f9fbbffbd219d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 19 Feb 2004 16:48:16 +0000 Subject: merging smbmnt fix from 3.0 (This used to be commit ea83c341c9ff54dfc5d0a941be96e6684f565d7d) --- source3/client/smbmnt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/client/smbmnt.c b/source3/client/smbmnt.c index c04be3b7af..753a31c313 100644 --- a/source3/client/smbmnt.c +++ b/source3/client/smbmnt.c @@ -240,7 +240,7 @@ do_mount(char *share_name, unsigned int flags, struct smb_mount_data *data) data.dir_mode |= S_IXOTH; } - flags = MS_MGC_VAL; + flags = MS_MGC_VAL | MS_NOSUID | MS_NODEV; if (mount_ro) flags |= MS_RDONLY; -- cgit From e8cc387efa9a4844975d44350081aa62d4546e7b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 19 Feb 2004 17:33:28 +0000 Subject: fixing error in logic when checking flags changed field on user primary group sid (This used to be commit c275d8f831490a52bae11698349a6b795d12f924) --- source3/rpc_server/srv_samr_util.c | 56 +++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index d54a858878..706c893c92 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -218,21 +218,21 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) SAFE_FREE(newstr); } - if ((from->fields_present & ACCT_RID) && - (from->user_rid == 0)) { - DEBUG(10, ("INFO_21: Asked to set User RID to 0 !? Skipping change!\n")); - } else if (from->user_rid != pdb_get_user_rid(to)) { - DEBUG(10,("INFO_21 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid)); - /* we really allow this ??? metze */ - /* pdb_set_user_sid_from_rid(to, from->user_rid, PDB_CHANGED);*/ + if (from->fields_present & ACCT_RID) { + if (from->user_rid == 0) { + DEBUG(10, ("INFO_21: Asked to set User RID to 0 !? Skipping change!\n")); + } else if (from->user_rid != pdb_get_user_rid(to)) { + DEBUG(10,("INFO_21 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid)); + } } - if ((from->fields_present & ACCT_PRIMARY_GID) && - (from->group_rid == 0)) { - DEBUG(10, ("INFO_21: Asked to set Group RID to 0 !? Skipping change!\n")); - } else if (from->group_rid != pdb_get_group_rid(to)) { - DEBUG(10,("INFO_21 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid)); - pdb_set_group_sid_from_rid(to, from->group_rid, PDB_CHANGED); + if (from->fields_present & ACCT_PRIMARY_GID) { + if (from->group_rid == 0) { + DEBUG(10, ("INFO_21: Asked to set Group RID to 0 !? Skipping change!\n")); + } else if (from->group_rid != pdb_get_group_rid(to)) { + DEBUG(10,("INFO_21 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid)); + pdb_set_group_sid_from_rid(to, from->group_rid, PDB_CHANGED); + } } if (from->fields_present & ACCT_FLAGS) { @@ -474,21 +474,21 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) SAFE_FREE(newstr); } - if ((from->fields_present & ACCT_RID) && - (from->user_rid == 0)) { - DEBUG(10, ("INFO_23: Asked to set User RID to 0 !? Skipping change!\n")); - } else if (from->user_rid != pdb_get_user_rid(to)) { - DEBUG(10,("INFO_23 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid)); - /* we really allow this ??? metze */ - /* pdb_set_user_sid_from_rid(to, from->user_rid, PDB_CHANGED);*/ - } - - if ((from->fields_present & ACCT_PRIMARY_GID) && - (from->group_rid == 0)) { - DEBUG(10, ("INFO_23: Asked to set Group RID to 0 !? Skipping change!\n")); - } else if (from->group_rid != pdb_get_group_rid(to)) { - DEBUG(10,("INFO_23 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid)); - pdb_set_group_sid_from_rid(to, from->group_rid, PDB_CHANGED); + if (from->fields_present & ACCT_RID) { + if (from->user_rid == 0) { + DEBUG(10, ("INFO_23: Asked to set User RID to 0 !? Skipping change!\n")); + } else if (from->user_rid != pdb_get_user_rid(to)) { + DEBUG(10,("INFO_23 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid)); + } + } + + if (from->fields_present & ACCT_PRIMARY_GID) { + if (from->group_rid == 0) { + DEBUG(10, ("INFO_23: Asked to set Group RID to 0 !? Skipping change!\n")); + } else if (from->group_rid != pdb_get_group_rid(to)) { + DEBUG(10,("INFO_23 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid)); + pdb_set_group_sid_from_rid(to, from->group_rid, PDB_CHANGED); + } } if (from->fields_present & ACCT_FLAGS) { -- cgit From db4623b2209a26e93ef0b7c95d8b1f4ee7328717 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 19 Feb 2004 18:35:46 +0000 Subject: Add bad pw count and autolock flag update fn()s (This used to be commit 91ea29b392ff05311e9631467ee6255b29887e04) --- source3/passdb/passdb.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 2 deletions(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index ddba4c6897..86e3af4a2a 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1395,7 +1395,7 @@ BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) &logon_count, &unknown_6); - if (len == -1) { + if (len == (uint32) -1) { ret = False; goto done; } @@ -1811,7 +1811,7 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) &logon_count, &unknown_6); - if (len == -1) { + if (len == (uint32) -1) { ret = False; goto done; } @@ -2198,3 +2198,128 @@ BOOL get_free_rid_range(uint32 *low, uint32 *high) return True; } + +/********************************************************************* + Update the bad password count checking the AP_RESET_COUNT_TIME +*********************************************************************/ + +BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated) +{ + time_t LastBadPassword; + uint16 BadPasswordCount; + uint32 resettime; + + BadPasswordCount = pdb_get_bad_password_count(sampass); + if(BadPasswordCount > 0){ + if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) { + DEBUG(0, ("account_policy_get failed.\n")); + return False; + } else { + LastBadPassword = pdb_get_bad_password_time(sampass); + DEBUG(10, ("LastBadPassword=%d, resettime=%d.\n", + (uint32) LastBadPassword, resettime)); + if (resettime && + (time(NULL) > (LastBadPassword + + (time_t)resettime*60))){ + pdb_set_bad_password_count(sampass, + 0, PDB_CHANGED); + pdb_set_bad_password_time(sampass, 0, + PDB_CHANGED); + *updated =True; + } + } + } + return True; +} + +/********************************************************************* + Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION +*********************************************************************/ + +BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated) +{ + uint32 duration; + time_t LastBadPassword; + + if (!sampass) + return False; + + if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) { + if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, + &duration)) { + DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n")); + return False; + } else { + LastBadPassword = pdb_get_bad_password_time(sampass); + DEBUG(10, ("LastBadPassword=%d, duration=%d.\n", + (uint32) LastBadPassword, duration*60 )); + if (duration && + (time(NULL) > + (LastBadPassword + (time_t)duration*60))){ + DEBUG(10, ("LastBadPassword=%d, duration=%d.\n", + (uint32) LastBadPassword, + duration*60 )); + pdb_set_acct_ctrl(sampass, + pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK, + PDB_CHANGED); + pdb_set_bad_password_count(sampass, + 0, PDB_CHANGED); + pdb_set_bad_password_time(sampass, 0, + PDB_CHANGED); + *updated =True; + } + } + } + + return True; +} + +/********************************************************************* + Increment the bad_password_count +*********************************************************************/ + +BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass) +{ + uint32 resettime; + uint32 account_policy_lockout; + time_t LastBadPassword; + + if (!sampass) + return False; + + if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) { + DEBUG(0, ("account_policy_get failed.\n")); + return False; + } else { + LastBadPassword = pdb_get_bad_password_time(sampass); + DEBUG(10, ("LastBadPassword=%d, resettime=%d.\n", + (uint32) LastBadPassword, resettime)); + DEBUG(10, ("time(null) = %d\n", (uint32) time(NULL))); + if ((resettime) && (LastBadPassword) && + (time(NULL) > (LastBadPassword + (time_t)resettime*60))){ + pdb_set_bad_password_count(sampass, 1, PDB_CHANGED); + } else { + pdb_set_bad_password_count(sampass, + pdb_get_bad_password_count(sampass)+1, + PDB_CHANGED); + } + pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED); + + if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, + &account_policy_lockout)) { + DEBUG(0, ("account_policy_get failed.\n")); + return False; + } else { + if (account_policy_lockout && + (pdb_get_bad_password_count(sampass) >= account_policy_lockout)) { + if (!pdb_set_acct_ctrl (sampass, + pdb_get_acct_ctrl(sampass) |ACB_AUTOLOCK, + PDB_CHANGED)) { + DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n")); + return False; + } + } + } + return True; + } +} -- cgit From 130cf14673d36129637e286803b7e9e2771b7cdc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 19 Feb 2004 19:35:48 +0000 Subject: comment out server portion of DsEnumerateDomainTrusts() since it causes 2k/xp clients to fail to join the domain (see comments in srv_netlog_nt.c for details) (This used to be commit 981bd70a56094740daf6d144f7b802370c0d9056) --- source3/rpc_server/srv_netlog.c | 4 ++++ source3/rpc_server/srv_netlog_nt.c | 11 +++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c index 0ef9b088a9..f06a2002e3 100644 --- a/source3/rpc_server/srv_netlog.c +++ b/source3/rpc_server/srv_netlog.c @@ -321,6 +321,7 @@ static BOOL api_net_logon_ctrl(pipes_struct *p) api_ds_enum_dom_trusts: *************************************************************************/ +#if 0 /* JERRY */ static BOOL api_ds_enum_dom_trusts(pipes_struct *p) { DS_Q_ENUM_DOM_TRUSTS q_u; @@ -350,6 +351,7 @@ static BOOL api_ds_enum_dom_trusts(pipes_struct *p) return True; } +#endif /* JERRY */ /******************************************************************* array of \PIPE\NETLOGON operations @@ -365,7 +367,9 @@ static struct api_struct api_net_cmds [] = { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 }, { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list }, { "NET_LOGON_CTRL" , NET_LOGON_CTRL , api_net_logon_ctrl }, +#if 0 /* JERRY */ { "DS_ENUM_DOM_TRUSTS", DS_ENUM_DOM_TRUSTS, api_ds_enum_dom_trusts } +#endif /* JERRY */ }; void netlog_get_pipe_fns( struct api_struct **fns, int *n_fns ) diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 65ebef8809..2f301a794c 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -770,15 +770,18 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * /************************************************************************* _ds_enum_dom_trusts *************************************************************************/ +#if 0 /* JERRY -- not correct */ NTSTATUS _ds_enum_dom_trusts(pipes_struct *p, DS_Q_ENUM_DOM_TRUSTS *q_u, DS_R_ENUM_DOM_TRUSTS *r_u) { NTSTATUS status = NT_STATUS_OK; - /* We just return zero trusts for now. At least that way we're - consistent with NetTrustedDomainList which is what the fallback - for this function is. Both of these functions need to be - reworked. */ + /* TODO: According to MSDN, the can only be executed against a + DC or domain member running Windows 2000 or later. Need + to test against a standalone 2k server and see what it + does. A windows 2000 DC includes its own domain in the + list. --jerry */ return status; } +#endif /* JERRY */ -- cgit From 85cc9a3830a29fa0ffedf62d40a399954f2681e3 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 19 Feb 2004 21:37:53 +0000 Subject: Clean up bad pw count and autolock flag update fn()s (This used to be commit 81dc9d53eb330f350f3f31068fe75c3606221e62) --- source3/passdb/passdb.c | 174 ++++++++++++++++++++++++++---------------------- 1 file changed, 95 insertions(+), 79 deletions(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 86e3af4a2a..1f1b5bdae6 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -2209,26 +2209,34 @@ BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated) uint16 BadPasswordCount; uint32 resettime; + if (!sampass) return False; + BadPasswordCount = pdb_get_bad_password_count(sampass); - if(BadPasswordCount > 0){ - if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) { - DEBUG(0, ("account_policy_get failed.\n")); - return False; - } else { - LastBadPassword = pdb_get_bad_password_time(sampass); - DEBUG(10, ("LastBadPassword=%d, resettime=%d.\n", - (uint32) LastBadPassword, resettime)); - if (resettime && - (time(NULL) > (LastBadPassword + - (time_t)resettime*60))){ - pdb_set_bad_password_count(sampass, - 0, PDB_CHANGED); - pdb_set_bad_password_time(sampass, 0, - PDB_CHANGED); - *updated =True; - } - } + if (!BadPasswordCount) { + DEBUG(9, ("No bad password attempts.\n")); + return True; + } + + if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) { + DEBUG(0, ("pdb_update_bad_password_count: account_policy_get failed.\n")); + return False; + } + + /* First, check if there is a reset time to compare */ + if (!resettime) { + DEBUG(9, ("Reset time = 0, can't reset bad pw count\n")); + return True; + } + + LastBadPassword = pdb_get_bad_password_time(sampass); + DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n", + (uint32) LastBadPassword, resettime, (uint32)time(NULL))); + if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){ + pdb_set_bad_password_count(sampass, 0, PDB_CHANGED); + pdb_set_bad_password_time(sampass, 0, PDB_CHANGED); + if (updated) *updated = True; } + return True; } @@ -2241,36 +2249,36 @@ BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated) uint32 duration; time_t LastBadPassword; - if (!sampass) - return False; + if (!sampass) return False; - if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) { - if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, - &duration)) { - DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n")); - return False; - } else { - LastBadPassword = pdb_get_bad_password_time(sampass); - DEBUG(10, ("LastBadPassword=%d, duration=%d.\n", - (uint32) LastBadPassword, duration*60 )); - if (duration && - (time(NULL) > - (LastBadPassword + (time_t)duration*60))){ - DEBUG(10, ("LastBadPassword=%d, duration=%d.\n", - (uint32) LastBadPassword, - duration*60 )); - pdb_set_acct_ctrl(sampass, - pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK, - PDB_CHANGED); - pdb_set_bad_password_count(sampass, - 0, PDB_CHANGED); - pdb_set_bad_password_time(sampass, 0, - PDB_CHANGED); - *updated =True; - } - } + if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) { + DEBUG(9, ("Account not autolocked, no check needed\n")); + return True; } + if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, &duration)) { + DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n")); + return False; + } + + /* First, check if there is a duration to compare */ + if (!duration) { + DEBUG(9, ("Lockout duration = 0, can't reset autolock\n")); + return True; + } + + LastBadPassword = pdb_get_bad_password_time(sampass); + DEBUG(7, ("LastBadPassword=%d, duration=%d, current time =%d.\n", + (uint32)LastBadPassword, duration*60, (uint32)time(NULL))); + if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) { + pdb_set_acct_ctrl(sampass, + pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK, + PDB_CHANGED); + pdb_set_bad_password_count(sampass, 0, PDB_CHANGED); + pdb_set_bad_password_time(sampass, 0, PDB_CHANGED); + if (updated) *updated = True; + } + return True; } @@ -2280,46 +2288,54 @@ BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated) BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass) { - uint32 resettime; uint32 account_policy_lockout; - time_t LastBadPassword; + BOOL autolock_updated = False, badpw_updated = False; if (!sampass) return False; - - if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) { - DEBUG(0, ("account_policy_get failed.\n")); + + /* Retrieve the account lockout policy */ + if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, + &account_policy_lockout)) { + DEBUG(0, ("pdb_increment_bad_password_count: account_policy_get failed.\n")); return False; - } else { - LastBadPassword = pdb_get_bad_password_time(sampass); - DEBUG(10, ("LastBadPassword=%d, resettime=%d.\n", - (uint32) LastBadPassword, resettime)); - DEBUG(10, ("time(null) = %d\n", (uint32) time(NULL))); - if ((resettime) && (LastBadPassword) && - (time(NULL) > (LastBadPassword + (time_t)resettime*60))){ - pdb_set_bad_password_count(sampass, 1, PDB_CHANGED); - } else { - pdb_set_bad_password_count(sampass, - pdb_get_bad_password_count(sampass)+1, - PDB_CHANGED); - } - pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED); + } - if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, - &account_policy_lockout)) { - DEBUG(0, ("account_policy_get failed.\n")); - return False; - } else { - if (account_policy_lockout && - (pdb_get_bad_password_count(sampass) >= account_policy_lockout)) { - if (!pdb_set_acct_ctrl (sampass, - pdb_get_acct_ctrl(sampass) |ACB_AUTOLOCK, - PDB_CHANGED)) { - DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n")); - return False; - } - } - } + /* If there is no policy, we don't need to continue checking */ + if (!account_policy_lockout) { + DEBUG(9, ("No lockout policy, don't track bad passwords\n")); return True; } + + /* Check if the autolock needs to be cleared */ + if (!pdb_update_autolock_flag(sampass, &autolock_updated)) + return False; + + /* Check if the badpw count needs to be reset */ + if (!pdb_update_bad_password_count(sampass, &badpw_updated)) + return False; + + /* + Ok, now we can assume that any resetting that needs to be + done has been done, and just get on with incrementing + and autolocking if necessary + */ + + pdb_set_bad_password_count(sampass, + pdb_get_bad_password_count(sampass)+1, + PDB_CHANGED); + pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED); + + + if (pdb_get_bad_password_count(sampass) < account_policy_lockout) + return True; + + if (!pdb_set_acct_ctrl(sampass, + pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK, + PDB_CHANGED)) { + DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n")); + return False; + } + + return True; } -- cgit From 62ea77ad1188c86c0dc6c3dd98757a437c528682 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 19 Feb 2004 21:41:03 +0000 Subject: Enable checking/resetting of account lockout and bad password based on policy (This used to be commit caef425d803fa01aa6f54339f8bc17fc752f73b0) --- source3/utils/pdbedit.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 733a1289da..541dc33a08 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -192,11 +192,12 @@ static int print_user_info (struct pdb_context *in, const char *username, BOOL v { SAM_ACCOUNT *sam_pwent=NULL; BOOL ret; - + BOOL updated_autolock = False, updated_badpw = False; + if (!NT_STATUS_IS_OK(pdb_init_sam (&sam_pwent))) { return -1; } - + ret = NT_STATUS_IS_OK(in->pdb_getsampwnam (in, sam_pwent, username)); if (ret==False) { @@ -204,7 +205,20 @@ static int print_user_info (struct pdb_context *in, const char *username, BOOL v pdb_free_sam(&sam_pwent); return -1; } - + + if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) + DEBUG(2,("pdb_update_autolock_flag failed.\n")); + + if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw)) + DEBUG(2,("pdb_update_bad_password_count failed.\n")); + + if (updated_autolock || updated_badpw) { + become_root(); + if(!pdb_update_sam_account(sam_pwent)) + DEBUG(1, ("Failed to modify entry.\n")); + unbecome_root(); + } + ret=print_sam_info (sam_pwent, verbosity, smbpwdstyle); pdb_free_sam(&sam_pwent); -- cgit From ee5e7e49251f9149367dcf0fb5f2d49d88d9a330 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 19 Feb 2004 21:55:45 +0000 Subject: remove some unused local variables (This used to be commit aa67c77515097cc21a9de727bf3722c04de313f9) --- source3/param/config_ldap.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source3/param/config_ldap.c b/source3/param/config_ldap.c index ad9b515381..1413fe158c 100644 --- a/source3/param/config_ldap.c +++ b/source3/param/config_ldap.c @@ -80,11 +80,9 @@ static NTSTATUS parse_section( LDAPMessage *result = NULL; LDAPMessage *entry = NULL; pstring filter; - pstring suffix; pstring option_name; pstring option_value; char **attr_list = NULL; - char *temp; int rc; int count; @@ -156,14 +154,13 @@ static NTSTATUS ldap_config_load( LDAPMessage *result = NULL; LDAPMessage *entry = NULL; pstring filter; - pstring suffix; pstring attr_text; char *config_dn = NULL; char *temp; int rc; int count; - char *config_attr_list[] = {"description", NULL}; - char *share_attr_list[] = {"sambaShareName", "description", NULL}; + const char *config_attr_list[] = {"description", NULL}; + const char *share_attr_list[] = {"sambaShareName", "description", NULL}; char **share_dn; char **share_name; -- cgit From 1568785f699d7616bd2028d4fa3269adf8663de1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 19 Feb 2004 21:56:49 +0000 Subject: check for ; needed by Debian testing (This used to be commit fb90b4140ec45ff4088c41dffce3680b5c4dc170) --- source3/configure.in | 2 +- source3/include/includes.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index 7cc42fe5bd..0dd5813527 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -625,7 +625,7 @@ AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/ AC_CHECK_HEADERS(nss.h nss_common.h nsswitch.h ns_api.h sys/security.h security/pam_appl.h security/pam_modules.h) AC_CHECK_HEADERS(stropts.h poll.h) AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h) -AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/cdefs.h glob.h) +AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/xattr.h sys/cdefs.h glob.h) # For experimental utmp support (lastlog on some BSD-like systems) AC_CHECK_HEADERS(utmp.h utmpx.h lastlog.h) diff --git a/source3/include/includes.h b/source3/include/includes.h index 1867aeda12..5b0e6cd7d2 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -441,6 +441,10 @@ #include #endif +#if HAVE_SYS_XATTR_H +#include +#endif + #if HAVE_LOCALE_H #include #endif -- cgit From be533b6915f32934f9e8d34f299846f42038dd1d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Feb 2004 23:01:52 +0000 Subject: Fixup returns from lookupsids in the same way as lookupnames. Inspired by Volkers patch. Jeremy. (This used to be commit aff6bacf0e461322e6e165cb7a6a42f4d976f52b) --- source3/rpc_server/srv_lsa_nt.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index ddf79ef564..aa933f9d0d 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -174,7 +174,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2, (*mapped_count)++; } else { dom_idx = -1; - rid = 0xffffffff; + rid = 0; name_type = SID_NAME_UNKNOWN; } @@ -202,11 +202,6 @@ static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l, r_l->dom_rid = rid2; r_l->mapped_count = mapped_count; - - if (mapped_count == 0) - r_l->status = NT_STATUS_NONE_MAPPED; - else - r_l->status = NT_STATUS_OK; } /*************************************************************************** @@ -711,6 +706,12 @@ done: /* set up the LSA Lookup RIDs response */ init_lsa_rid2s(ref, rids, num_entries, names, &mapped_count, p->endian); + if (mapped_count == 0) + r_u->status = NT_STATUS_NONE_MAPPED; + else if (mapped_count != num_entries) + r_u->status = STATUS_SOME_UNMAPPED; + else + r_u->status = NT_STATUS_OK; init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count); return r_u->status; -- cgit From db1e6c1bdb56fecd43d47324e32830e355641eae Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 20 Feb 2004 15:53:26 +0000 Subject: & are mutually exclusive it seems; fix build on SuSE 8.2 (This used to be commit bf271b96cf6bc42c8a23309d890febf003e1627f) --- source3/include/includes.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source3/include/includes.h b/source3/include/includes.h index 5b0e6cd7d2..db060907e4 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -437,11 +437,10 @@ #include #endif +/* mutually exclusive (SuSE 8.2) */ #if HAVE_ATTR_XATTR_H #include -#endif - -#if HAVE_SYS_XATTR_H +#elif HAVE_SYS_XATTR_H #include #endif -- cgit From 7f18e0d5bad573983476e542c8a339970625578f Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 20 Feb 2004 15:59:10 +0000 Subject: Make default lockout duration and reset count time 30 minutes, to match windows, and also be valid (0 was invalid) (This used to be commit 69924079b2f7098254c2053781121d4324626dee) --- source3/lib/account_pol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index dc131985a1..c2c63493a6 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -55,8 +55,8 @@ BOOL init_account_policy(void) account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, 0); /* don't force user to logon */ account_policy_set(AP_MAX_PASSWORD_AGE, (uint32)-1); /* don't expire */ account_policy_set(AP_MIN_PASSWORD_AGE, 0); /* 0 days */ - account_policy_set(AP_LOCK_ACCOUNT_DURATION, 0); /* lockout for 0 minutes */ - account_policy_set(AP_RESET_COUNT_TIME, 0); /* reset immediatly */ + account_policy_set(AP_LOCK_ACCOUNT_DURATION, 30); /* lockout for 30 minutes */ + account_policy_set(AP_RESET_COUNT_TIME, 30); /* reset after 30 minutes */ account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, 0); /* don't lockout */ account_policy_set(AP_TIME_TO_LOGOUT, -1); /* don't force logout */ } -- cgit From db3d07c2f5c0764bbf55c0a11a85ae2e52dc481f Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 20 Feb 2004 16:00:42 +0000 Subject: handle both 0 and -1 as disabling reset count and lockout duration (This used to be commit ad2996e418a45c1cf4f969077ffc267de70d6866) --- source3/passdb/passdb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 1f1b5bdae6..7c9376e045 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -2223,8 +2223,8 @@ BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated) } /* First, check if there is a reset time to compare */ - if (!resettime) { - DEBUG(9, ("Reset time = 0, can't reset bad pw count\n")); + if ((resettime == (uint32) -1) || (resettime == 0)) { + DEBUG(9, ("No reset time, can't reset bad pw count\n")); return True; } @@ -2262,8 +2262,8 @@ BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated) } /* First, check if there is a duration to compare */ - if (!duration) { - DEBUG(9, ("Lockout duration = 0, can't reset autolock\n")); + if ((duration == (uint32) -1) || (duration == 0)) { + DEBUG(9, ("No reset duration, can't reset autolock\n")); return True; } -- cgit From 9138aa18eb66d2c54cd0736c5e25800868c274f5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 20 Feb 2004 22:42:39 +0000 Subject: AIX has already has a function called msleep(). Bugzilla #1098. (This used to be commit 90ae3667448be9b3445f401bcd9d7e3eba374215) --- source3/lib/smbldap.c | 4 ++-- source3/lib/util.c | 2 +- source3/lib/util_sock.c | 2 +- source3/libsmb/clilist.c | 2 +- source3/libsmb/clirap.c | 4 ++-- source3/sam/idmap_ldap.c | 2 +- source3/torture/msgtest.c | 4 ++-- source3/torture/torture.c | 8 ++++---- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 925bc1fbf0..bb16517149 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -888,7 +888,7 @@ int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts) */ DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n", sleep_time)); - msleep(sleep_time); + smb_msleep(sleep_time); } (*attempts)++; @@ -935,7 +935,7 @@ int smbldap_search(struct smbldap_state *ldap_state, if (sleep_time > 0) { /* we wait for the LDAP replication */ DEBUG(5,("smbldap_search: waiting %d milliseconds for LDAP replication.\n",sleep_time)); - msleep(sleep_time); + smb_msleep(sleep_time); DEBUG(5,("smbldap_search: go on!\n")); ZERO_STRUCT(ldap_state->last_rebind); } diff --git a/source3/lib/util.c b/source3/lib/util.c index 61dbc2cb2a..f169a3103e 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -769,7 +769,7 @@ SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n) Sleep for a specified number of milliseconds. ********************************************************************/ -void msleep(unsigned int t) +void smb_msleep(unsigned int t) { unsigned int tdiff=0; struct timeval tval,t1,t2; diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 782f5f3f73..a275ddabb9 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -740,7 +740,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) /* Some systems return EAGAIN when they mean EINPROGRESS */ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN) && (connect_loop < timeout) ) { - msleep(connect_loop); + smb_msleep(connect_loop); connect_loop += increment; if (increment < 250) { /* After 8 rounds we end up at a max of 255 msec */ diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2c1831ae99..ab157d48e9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -232,7 +232,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); + smb_msleep(100); continue; } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 36bc403e0b..e403a78cdd 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -408,7 +408,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, uint32 ecode; cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); + smb_msleep(100); } } while (count-- && ret==False); @@ -715,7 +715,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin uint32 ecode; cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); + smb_msleep(100); } } while (count-- && ret==False); diff --git a/source3/sam/idmap_ldap.c b/source3/sam/idmap_ldap.c index a2afd7d424..55f4578448 100644 --- a/source3/sam/idmap_ldap.c +++ b/source3/sam/idmap_ldap.c @@ -351,7 +351,7 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, attempts += 1; sleeptime %= 100; - msleep(sleeptime); + smb_msleep(sleeptime); } } diff --git a/source3/torture/msgtest.c b/source3/torture/msgtest.c index 8abb0a20d2..c40973a75c 100644 --- a/source3/torture/msgtest.c +++ b/source3/torture/msgtest.c @@ -63,7 +63,7 @@ void pong_message(int msg_type, pid_t src, void *buf, size_t len) while (pong_count < i) { message_dispatch(); - msleep(1); + smb_msleep(1); } /* Now test that the duplicate filtering code works. */ @@ -78,7 +78,7 @@ void pong_message(int msg_type, pid_t src, void *buf, size_t len) for (i=0;i Date: Fri, 20 Feb 2004 22:45:49 +0000 Subject: Make us bug-for-bug compatible with W2K3 - to get delete on close semantics on an initial open the desired_access field *must* contain DELETE_ACCESS, simply having it map from a GENERIC_ALL won't do. Fixes delete on close test. Jeremy. (This used to be commit fb4249e7d12bee4589edff40f1e76f1a19a6ffaa) --- source3/libsmb/clirap.c | 11 ++++++++--- source3/smbd/nttrans.c | 25 +++++++++++++++++++------ source3/torture/torture.c | 26 +++++++++++++++++--------- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index e403a78cdd..721d3dcb47 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -631,7 +631,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, /**************************************************************************** send a qfileinfo call ****************************************************************************/ -BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata) +BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutdata, uint32 *poutlen) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -639,9 +639,13 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat pstring param; char *rparam=NULL, *rdata=NULL; + *poutdata = NULL; + *poutlen = 0; + /* if its a win95 server then fail this - win95 totally screws it up */ - if (cli->win95) return False; + if (cli->win95) + return False; param_len = 4; @@ -665,7 +669,8 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat return False; } - memcpy(outdata, rdata, data_len); + memdup(poutdata, data_len); + *poutlen = data_len; SAFE_FREE(rdata); SAFE_FREE(rparam); diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 0a2843629e..075b549a10 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -354,6 +354,7 @@ static int map_share_mode( char *fname, uint32 create_options, uint32 *desired_access, uint32 share_access, uint32 file_attributes) { int smb_open_mode = -1; + uint32 original_desired_access = *desired_access; /* * Convert GENERIC bits to specific bits. @@ -425,6 +426,10 @@ static int map_share_mode( char *fname, uint32 create_options, DEBUG(10,("map_share_mode: FILE_SHARE_DELETE requested. open_mode = 0x%x\n", smb_open_mode)); } + if(*desired_access & DELETE_ACCESS) { + DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode)); + } + /* * We need to store the intent to open for Delete. This * is what determines if a delete on close flag can be set. @@ -432,11 +437,19 @@ static int map_share_mode( char *fname, uint32 create_options, * is the only practical way. JRA. */ - if(*desired_access & DELETE_ACCESS) { - DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode)); - } - if (create_options & FILE_DELETE_ON_CLOSE) { + /* + * W2K3 bug compatibility mode... To set delete on close + * the redirector must have *specifically* set DELETE_ACCESS + * in the desired_access field. Just asking for GENERIC_ALL won't do. JRA. + */ + + if (!(original_desired_access & DELETE_ACCESS)) { + DEBUG(5,("map_share_mode: FILE_DELETE_ON_CLOSE requested without \ +DELETE_ACCESS for file %s. (desired_access = 0x%lx)\n", + fname, (unsigned long)*desired_access)); + return -1; + } /* Implicit delete access is *NOT* requested... */ smb_open_mode |= DELETE_ON_CLOSE_FLAG; DEBUG(10,("map_share_mode: FILE_DELETE_ON_CLOSE requested. open_mode = 0x%x\n", smb_open_mode)); @@ -739,7 +752,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib share_access, file_attributes)) == -1) { END_PROFILE(SMBntcreateX); - return ERROR_DOS(ERRDOS,ERRnoaccess); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; @@ -1268,7 +1281,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o if((smb_open_mode = map_share_mode( fname, create_options, &desired_access, share_access, file_attributes)) == -1) - return ERROR_DOS(ERRDOS,ERRnoaccess); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 9d0a6bb79e..e612ddea92 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -2493,19 +2493,19 @@ static BOOL run_trans2test(int dummy) static BOOL new_trans(struct cli_state *pcli, int fnum, int level) { - char buf[4096]; + char *buf = NULL; + uint32 len; BOOL correct = True; - memset(buf, 0xff, sizeof(buf)); - - if (!cli_qfileinfo_test(pcli, fnum, level, buf)) { + if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) { printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli)); correct = False; } else { - printf("qfileinfo: level %d\n", level); - dump_data(0, buf, 256); + printf("qfileinfo: level %d, len = %u\n", level, len); + dump_data(0, buf, len); printf("\n"); } + SAFE_FREE(buf); return correct; } @@ -2812,8 +2812,8 @@ static BOOL run_deletetest(int dummy) cli_setatr(cli1, fname, 0, 0); cli_unlink(cli1, fname); - fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_DELETE, FILE_OVERWRITE_IF, + fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL, + 0, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0); if (fnum1 == -1) { @@ -2821,7 +2821,15 @@ static BOOL run_deletetest(int dummy) correct = False; goto fail; } - + +#if 0 + { + uint32 accinfo = 0; + cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char *)&accinfo); + printf("access mode = 0x%lx\n", accinfo); + } +#endif + if (!cli_close(cli1, fnum1)) { printf("[1] close failed (%s)\n", cli_errstr(cli1)); correct = False; -- cgit From e1b5599cc7f138424bbcec87822e6f5d3672d286 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Feb 2004 23:19:36 +0000 Subject: Make SMB_FILE_ACCESS_INFORMATION call work correctly. Jeremy. (This used to be commit a6cb7af9bad1610e802fa5cddbf68fb887bc2974) --- source3/include/tdbsam2_parse_info.h | 107 ----------------------------------- source3/libsmb/clirap.c | 2 +- source3/smbd/trans2.c | 4 +- source3/torture/torture.c | 15 +++-- 4 files changed, 13 insertions(+), 115 deletions(-) diff --git a/source3/include/tdbsam2_parse_info.h b/source3/include/tdbsam2_parse_info.h index abaa2b142a..35eeaeb2d2 100644 --- a/source3/include/tdbsam2_parse_info.h +++ b/source3/include/tdbsam2_parse_info.h @@ -1,109 +1,2 @@ /* This is an automatically generated file - DO NOT EDIT! */ -int gen_dump_struct_gums_user(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_gums_user(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_gums_user[] = { -{"group_sid", 1, sizeof(DOM_SID), offsetof(struct gums_user, group_sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, -{"logon_time", 0, sizeof(NTTIME), offsetof(struct gums_user, logon_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"logoff_time", 0, sizeof(NTTIME), offsetof(struct gums_user, logoff_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"kickoff_time", 0, sizeof(NTTIME), offsetof(struct gums_user, kickoff_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"pass_last_set_time", 0, sizeof(NTTIME), offsetof(struct gums_user, pass_last_set_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"pass_can_change_time", 0, sizeof(NTTIME), offsetof(struct gums_user, pass_can_change_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"pass_must_change_time", 0, sizeof(NTTIME), offsetof(struct gums_user, pass_must_change_time), 0, NULL, 0, gen_dump_NTTIME, gen_parse_NTTIME}, -{"full_name", 1, sizeof(char), offsetof(struct gums_user, full_name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"home_dir", 1, sizeof(char), offsetof(struct gums_user, home_dir), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"dir_drive", 1, sizeof(char), offsetof(struct gums_user, dir_drive), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"logon_script", 1, sizeof(char), offsetof(struct gums_user, logon_script), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"profile_path", 1, sizeof(char), offsetof(struct gums_user, profile_path), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"workstations", 1, sizeof(char), offsetof(struct gums_user, workstations), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"unknown_str", 1, sizeof(char), offsetof(struct gums_user, unknown_str), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"munged_dial", 1, sizeof(char), offsetof(struct gums_user, munged_dial), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"lm_pw", 0, sizeof(DATA_BLOB), offsetof(struct gums_user, lm_pw), 0, NULL, 0, gen_dump_DATA_BLOB, gen_parse_DATA_BLOB}, -{"nt_pw", 0, sizeof(DATA_BLOB), offsetof(struct gums_user, nt_pw), 0, NULL, 0, gen_dump_DATA_BLOB, gen_parse_DATA_BLOB}, -{"acct_ctrl", 0, sizeof(uint16), offsetof(struct gums_user, acct_ctrl), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, -{"logon_divs", 0, sizeof(uint16), offsetof(struct gums_user, logon_divs), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, -{"hours_len", 0, sizeof(uint32), offsetof(struct gums_user, hours_len), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"hours", 1, sizeof(uint8), offsetof(struct gums_user, hours), 0, "hours_len", 0, gen_dump_uint8, gen_parse_uint8}, -{"bad_password_count", 0, sizeof(uint16), offsetof(struct gums_user, bad_password_count), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, -{"logon_count", 0, sizeof(uint16), offsetof(struct gums_user, logon_count), 0, NULL, 0, gen_dump_uint16, gen_parse_uint16}, -{"unknown_3", 0, sizeof(uint32), offsetof(struct gums_user, unknown_3), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"unknown_6", 0, sizeof(uint32), offsetof(struct gums_user, unknown_6), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; - -int gen_dump_struct_gums_user(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_gums_user, p, ptr, indent); -} -int gen_parse_struct_gums_user(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_gums_user, ptr, str); -} - -int gen_dump_struct_gums_group(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_gums_group(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_gums_group[] = { -{"count", 0, sizeof(uint32), offsetof(struct gums_group, count), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"members", 1, sizeof(DOM_SID), offsetof(struct gums_group, members), 0, "count", 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, -{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; - -int gen_dump_struct_gums_group(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_gums_group, p, ptr, indent); -} -int gen_parse_struct_gums_group(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_gums_group, ptr, str); -} - -int gen_dump_struct_gums_domain(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_gums_domain(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_gums_domain[] = { -{"next_rid", 0, sizeof(uint32), offsetof(struct gums_domain, next_rid), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; - -int gen_dump_struct_gums_domain(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_gums_domain, p, ptr, indent); -} -int gen_parse_struct_gums_domain(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_gums_domain, ptr, str); -} - -int gen_dump_struct_gums_object(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_gums_object(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_gums_object[] = { -{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct gums_object, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX}, -{"type", 0, sizeof(uint32), offsetof(struct gums_object, type), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"version", 0, sizeof(uint32), offsetof(struct gums_object, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"seq_num", 0, sizeof(uint32), offsetof(struct gums_object, seq_num), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"sec_desc", 1, sizeof(SEC_DESC), offsetof(struct gums_object, sec_desc), 0, NULL, 0, gen_dump_SEC_DESC, gen_parse_SEC_DESC}, -{"sid", 1, sizeof(DOM_SID), offsetof(struct gums_object, sid), 0, NULL, 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, -{"name", 1, sizeof(char), offsetof(struct gums_object, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"description", 1, sizeof(char), offsetof(struct gums_object, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"user", 1, sizeof(struct gums_user), offsetof(struct gums_object, user), 0, NULL, 0, gen_dump_struct_gums_user, gen_parse_struct_gums_user}, -{"group", 1, sizeof(struct gums_group), offsetof(struct gums_object, group), 0, NULL, 0, gen_dump_struct_gums_group, gen_parse_struct_gums_group}, -{"domain", 1, sizeof(struct gums_domain), offsetof(struct gums_object, domain), 0, NULL, 0, gen_dump_struct_gums_domain, gen_parse_struct_gums_domain}, -{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; - -int gen_dump_struct_gums_object(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_gums_object, p, ptr, indent); -} -int gen_parse_struct_gums_object(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_gums_object, ptr, str); -} - -int gen_dump_struct_gums_privilege(TALLOC_CTX *mem_ctx, struct parse_string *, const char *, unsigned); -int gen_parse_struct_gums_privilege(TALLOC_CTX *mem_ctx, char *, const char *); -static const struct parse_struct pinfo_gums_privilege[] = { -{"mem_ctx", 1, sizeof(TALLOC_CTX), offsetof(struct gums_privilege, mem_ctx), 0, NULL, 0, gen_dump_TALLOC_CTX, gen_parse_TALLOC_CTX}, -{"version", 0, sizeof(uint32), offsetof(struct gums_privilege, version), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"seq_num", 0, sizeof(uint32), offsetof(struct gums_privilege, seq_num), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"name", 1, sizeof(char), offsetof(struct gums_privilege, name), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"description", 1, sizeof(char), offsetof(struct gums_privilege, description), 0, NULL, FLAG_NULLTERM, gen_dump_char, gen_parse_char}, -{"privilege", 1, sizeof(LUID_ATTR), offsetof(struct gums_privilege, privilege), 0, NULL, 0, gen_dump_LUID_ATTR, gen_parse_LUID_ATTR}, -{"count", 0, sizeof(uint32), offsetof(struct gums_privilege, count), 0, NULL, 0, gen_dump_uint32, gen_parse_uint32}, -{"members", 1, sizeof(DOM_SID), offsetof(struct gums_privilege, members), 0, "count", 0, gen_dump_DOM_SID, gen_parse_DOM_SID}, -{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}}; - -int gen_dump_struct_gums_privilege(TALLOC_CTX *mem_ctx, struct parse_string *p, const char *ptr, unsigned indent) { - return gen_dump_struct(mem_ctx, pinfo_gums_privilege, p, ptr, indent); -} -int gen_parse_struct_gums_privilege(TALLOC_CTX *mem_ctx, char *ptr, const char *str) { - return gen_parse_struct(mem_ctx, pinfo_gums_privilege, ptr, str); -} - diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 721d3dcb47..f8204e05d6 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -669,7 +669,7 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutd return False; } - memdup(poutdata, data_len); + *poutdata = memdup(rdata, data_len); *poutlen = data_len; SAFE_FREE(rdata); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 525b015379..605169277d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1841,6 +1841,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, int len; time_t c_time; files_struct *fsp = NULL; + uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */ if (!params) return ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -1904,6 +1905,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, } pos = fsp->position_information; delete_pending = fsp->delete_on_close; + desired_access = fsp->desired_access; } } else { /* qpathinfo */ @@ -2152,7 +2154,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, break; case SMB_FILE_ACCESS_INFORMATION: - SIVAL(pdata,0,0x12019F); /* ??? */ + SIVAL(pdata,0,desired_access); data_size = 4; break; diff --git a/source3/torture/torture.c b/source3/torture/torture.c index e612ddea92..57ba24e63e 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -2822,12 +2822,15 @@ static BOOL run_deletetest(int dummy) goto fail; } -#if 0 - { - uint32 accinfo = 0; - cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char *)&accinfo); - printf("access mode = 0x%lx\n", accinfo); - } +#if 0 /* JRATEST */ + { + uint32 *accinfo = NULL; + uint32 len; + cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len); + if (accinfo) + printf("access mode = 0x%lx\n", *accinfo); + SAFE_FREE(accinfo); + } #endif if (!cli_close(cli1, fnum1)) { -- cgit From 9cc122329bc65883429b36098caeb8783fa7a58b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 21 Feb 2004 00:27:30 +0000 Subject: printf -> d_printf (This used to be commit 3f3a744e925aa943c901406f1565ebf346fe8707) --- source3/web/swat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/web/swat.c b/source3/web/swat.c index 1faef46e25..c536e12e09 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -197,7 +197,7 @@ static void show_parameter(int snum, struct parm_struct *parm) ptr = lp_local_ptr(snum, ptr); } - printf("%s", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label)); + d_printf("%s", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label)); switch (parm->type) { case P_CHAR: d_printf("", -- cgit From c64ff63349c0ed5409db1a20be8d9c5bce6ab501 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sat, 21 Feb 2004 17:41:32 +0000 Subject: Add calls to password lockout functions. Should now work against tdbsam only. (This used to be commit 6ccb90acfd8591f6ef0d91b4ada89c5ad8ac98d5) --- source3/auth/auth_sam.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index ebb1e3d861..b35cc78d6b 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -179,6 +179,7 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, NTSTATUS nt_status; DATA_BLOB user_sess_key = data_blob(NULL, 0); DATA_BLOB lm_sess_key = data_blob(NULL, 0); + BOOL updated_autolock = False, updated_badpw = False; if (!user_info || !auth_context) { return NT_STATUS_UNSUCCESSFUL; @@ -202,14 +203,51 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, return NT_STATUS_NO_SUCH_USER; } + /* see if autolock flag needs to be updated */ + if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) + pdb_update_autolock_flag(sampass, &updated_autolock); + /* Quit if the account was locked out. */ + if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) { + DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", pdb_get_username(sampass))); + return NT_STATUS_ACCOUNT_LOCKED_OUT; + } + nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, &user_sess_key, &lm_sess_key); if (!NT_STATUS_IS_OK(nt_status)) { + if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) && + pdb_get_acct_ctrl(sampass) &ACB_NORMAL) { + pdb_increment_bad_password_count(sampass); + updated_badpw = True; + } else { + pdb_update_bad_password_count(sampass, + &updated_badpw); + } + if (updated_autolock || updated_badpw){ + become_root(); + if(!pdb_update_sam_account(sampass)) + DEBUG(1, ("Failed to modify entry.\n")); + unbecome_root(); + } pdb_free_sam(&sampass); return nt_status; } + if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) && + (pdb_get_bad_password_count(sampass) > 0)){ + pdb_set_bad_password_count(sampass, 0, PDB_CHANGED); + pdb_set_bad_password_time(sampass, 0, PDB_CHANGED); + updated_badpw = True; + } + + if (updated_autolock || updated_badpw){ + become_root(); + if(!pdb_update_sam_account(sampass)) + DEBUG(1, ("Failed to modify entry.\n")); + unbecome_root(); + } + nt_status = sam_account_ok(mem_ctx, sampass, user_info); if (!NT_STATUS_IS_OK(nt_status)) { -- cgit From 6ba430dd8ec030359de0bc8295cb0db76912dbb0 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sun, 22 Feb 2004 20:25:39 +0000 Subject: Add bad password count/time attributes (This used to be commit 51a8d050e9242192c2670b09242cf4fdbbae8940) --- examples/LDAP/samba.schema | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema index 2f1b8e8ff2..12ce173028 100644 --- a/examples/LDAP/samba.schema +++ b/examples/LDAP/samba.schema @@ -202,6 +202,16 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributetype ( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount' + DESC 'Bad password attempt count' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime' + DESC 'Time of the last bad password attempt' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + ## ## string settings @@ -345,7 +355,8 @@ objectclass ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ - sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial)) + sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $ + sambaBadPasswordCount $ sambaBadPasswordTime)) ## ## Group mapping info -- cgit From 74112e7ccaff59bca963d07af3aa11520d5cb656 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 23 Feb 2004 02:47:27 +0000 Subject: Add bad password count/time attributes (This used to be commit 2fa56111d37a09702b31e1769a687b630aff1c1b) --- source3/include/smbldap.h | 1 + source3/lib/smbldap.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 14ea2de012..9ef66a14ef 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -91,6 +91,7 @@ #define LDAP_ATTR_BAD_PASSWORD_COUNT 35 #define LDAP_ATTR_LOGON_COUNT 36 #define LDAP_ATTR_MUNGED_DIAL 37 +#define LDAP_ATTR_BAD_PASSWORD_TIME 38 typedef struct _attrib_map_entry { int attrib; diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index bb16517149..fcebccc58a 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -98,6 +98,8 @@ ATTRIB_MAP_ENTRY attrib_map_v30[] = { { LDAP_ATTR_OBJCLASS, "objectClass" }, { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" }, { LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" }, + { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" }, + { LDAP_ATTR_BAD_PASSWORD_TIME, "sambaBadPasswordTime" }, { LDAP_ATTR_LIST_END, NULL } }; -- cgit From fab1291e284a40a9af95228e4a77be991cbf0fe0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 23 Feb 2004 20:12:15 +0000 Subject: Fix "unable to initialize" bug when smbd hasn't been run with new system and a user is being added via pdbedit/smbpasswd. Found at Connectathon setup. Jeremy. (This used to be commit 93580927dc255f205283b64c72fb95be990d2216) --- source3/utils/pdbedit.c | 4 ++++ source3/utils/smbpasswd.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 541dc33a08..3f7aba8366 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -398,6 +398,8 @@ static int new_user (struct pdb_context *in, const char *username, NTSTATUS nt_status; char *password1, *password2, *staticpass; + get_global_sam_sid(); + if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pwent, username, 0))) { DEBUG(0, ("could not create account to add new user %s\n", username)); return -1; @@ -490,6 +492,8 @@ static int new_machine (struct pdb_context *in, const char *machine_in) fstring machineaccount; struct passwd *pwd = NULL; + get_global_sam_sid(); + fstrcpy(machinename, machine_in); machinename[15]= '\0'; diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 6854842b20..ea8bf7a472 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -340,8 +340,7 @@ static int process_root(int local_flags) int result = 0; char *old_passwd = NULL; - if (local_flags & LOCAL_SET_LDAP_ADMIN_PW) - { + if (local_flags & LOCAL_SET_LDAP_ADMIN_PW) { printf("Setting stored password for \"%s\" in secrets.tdb\n", lp_ldap_admin_dn()); if (!store_ldap_admin_pw(ldap_secret)) @@ -349,6 +348,9 @@ static int process_root(int local_flags) goto done; } + /* Ensure we have a SAM sid. */ + get_global_sam_sid(); + /* * Ensure both add/delete user are not set * Ensure add/delete user and either remote machine or join domain are -- cgit From 397665a27375ee12d2b2c51370473cbe7d2ae2a4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 23 Feb 2004 21:10:16 +0000 Subject: (merge from 3.0) Found by Fabien Chevalier and JustFillBug on the Samba lists - a 'max password age' of zero should be considered as 'never expire'. For the timebeing we just set it like -1, but we might revisit this for closer-to-ms behaviour. Andrew Bartlett (This used to be commit 2003cdc65e1b9f6514d97334997fee5c49813bac) --- source3/passdb/pdb_get_set.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 3974115588..908588c898 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -1085,7 +1085,7 @@ BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass) return False; if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire) - || (expire==(uint32)-1)) { + || (expire==(uint32)-1) || (expire == 0)) { if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), PDB_CHANGED)) return False; } else { -- cgit From 61eedb268bad8cf0e605f25a8362f1bd1705dfe7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2004 00:02:58 +0000 Subject: Fixup correct timeout values for blocking lock timeouts (tested at connectathon by Herb). Jeremy. (This used to be commit 6356b792683100122500db9cf222b7e8518d834e) --- source3/smbd/reply.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c4ff77bd86..ee47485126 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -4288,7 +4288,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); /* Setup the timeout in seconds. */ - lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+499)/500); + lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000); /* Now do any requested locks */ data += ((large_file_format ? 20 : 10)*num_ulocks); -- cgit From bf6eb83a3851278668b0f7883113ad3836a65c23 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2004 00:05:49 +0000 Subject: Added NTrename SMB (0xA5) - how did we miss this.... ? Jeremy. (This used to be commit d236372876918be2a886a89383cf843b82d4c8db) --- source3/include/smb.h | 1 + source3/include/smbprofile.h | 4 +++- source3/smbd/nttrans.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ source3/smbd/process.c | 2 +- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/source3/include/smb.h b/source3/include/smb.h index 342c010124..1bf5db4768 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -873,6 +873,7 @@ struct bitmap { #define SMBnttranss 0xA1 /* NT transact secondary */ #define SMBntcreateX 0xA2 /* NT create and X */ #define SMBntcancel 0xA4 /* NT cancel */ +#define SMBntrename 0xA5 /* NT rename */ /* These are the trans subcommands */ #define TRANSACT_SETNAMEDPIPEHANDLESTATE 0x01 diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index c29a630fe5..e494faf7da 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -34,7 +34,7 @@ enum flush_reason_enum { SEEK_FLUSH, READ_FLUSH, WRITE_FLUSH, READRAW_FLUSH, #define PROF_SHMEM_KEY ((key_t)0x07021999) #define PROF_SHM_MAGIC 0x6349985 -#define PROF_SHM_VERSION 8 +#define PROF_SHM_VERSION 9 /* time values in the following structure are in microseconds */ @@ -259,6 +259,8 @@ struct profile_stats { unsigned SMBntcreateX_time; unsigned SMBntcancel_count; /* NT cancel */ unsigned SMBntcancel_time; + unsigned SMBntrename_count; /* NT rename file */ + unsigned SMBntrename_time; unsigned SMBsplopen_count; /* open print spool file */ unsigned SMBsplopen_time; unsigned SMBsplwr_count; /* write to print spool file */ diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 075b549a10..954d90b4ad 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1489,6 +1489,56 @@ int reply_ntcancel(connection_struct *conn, return(-1); } +/**************************************************************************** + Reply to a NT rename request. +****************************************************************************/ + +int reply_ntrename(connection_struct *conn, + char *inbuf,char *outbuf,int length,int bufsize) +{ + int outsize = 0; + pstring name; + pstring newname; + char *p; + NTSTATUS status; + + START_PROFILE(SMBntrename); + + p = smb_buf(inbuf) + 1; + p += srvstr_get_path(inbuf, name, p, sizeof(name), STR_TERMINATE,&status); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBntrename); + return ERROR_NT(status); + } + p++; + p += srvstr_get_path(inbuf, newname, p, sizeof(newname), STR_TERMINATE,&status); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBntrename); + return ERROR_NT(status); + } + + RESOLVE_DFSPATH(name, conn, inbuf, outbuf); + RESOLVE_DFSPATH(newname, conn, inbuf, outbuf); + + DEBUG(3,("reply_ntrename : %s -> %s\n",name,newname)); + + status = rename_internals(conn, name, newname, False); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBntrename); + return ERROR_NT(status); + } + + /* + * Win2k needs a changenotify request response before it will + * update after a rename.. + */ + process_pending_change_notify_queue((time_t)0); + outsize = set_message(outbuf,0,0,True); + + END_PROFILE(SMBntrename); + return(outsize); +} + /**************************************************************************** Reply to an unsolicited SMBNTtranss - just ignore it! ****************************************************************************/ diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 5206dc70f8..718d1bb67b 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -521,7 +521,7 @@ static const struct smb_message_struct { /* 0xa2 */ { "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK }, /* 0xa3 */ { NULL, NULL, 0 }, /* 0xa4 */ { "SMBntcancel", reply_ntcancel, 0 }, -/* 0xa5 */ { NULL, NULL, 0 }, +/* 0xa5 */ { "SMBntrename", reply_ntrename, AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK }, /* 0xa6 */ { NULL, NULL, 0 }, /* 0xa7 */ { NULL, NULL, 0 }, /* 0xa8 */ { NULL, NULL, 0 }, -- cgit From ad69d4db0a9852c97744602da924d3e1a4611601 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2004 00:38:24 +0000 Subject: Fixup bad-path error found by gentest. Jeremy. (This used to be commit 55f13d743e78ed8f48bf209e838ea77df3121047) --- source3/smbd/trans2.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 605169277d..63130aa8d8 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2540,9 +2540,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, info_level = SVAL(params,0); srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE); unix_convert(fname,conn,0,&bad_path,&sbuf); - if(!check_name(fname, conn)) { - return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); - } /* * For CIFS UNIX extensions the target name may not exist. @@ -2550,8 +2547,13 @@ static int call_trans2setfilepathinfo(connection_struct *conn, if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) { DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno))); - return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND); + return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); } + + if(!check_name(fname, conn)) { + return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); + } + } if (!CAN_WRITE(conn)) -- cgit From fb11e4a874593eb8426150322dfc0e7181e7b949 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2004 00:54:43 +0000 Subject: More gentest error fixups. Jeremy. (This used to be commit f353cafa9d9e6142b4aec45cfbc567dc4ab20d7e) --- source3/smbd/nttrans.c | 2 -- source3/smbd/open.c | 9 +++++++++ source3/smbd/reply.c | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 954d90b4ad..4e87f191d8 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -674,14 +674,12 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); } - /* we need to handle the case when we get a relative open relative to a file and the pathname is blank - this is a reopen! (hint from demyn plantenberg) */ - END_PROFILE(SMBntcreateX); return(ERROR_DOS(ERRDOS,ERRbadfid)); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 3807c18e78..dd10a87055 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1305,6 +1305,15 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST return NULL; } + if( strchr_m(fname, ':')) { + file_free(fsp); + DEBUG(5,("open_directory: failing create on filename %s with colon in name\n", fname)); + unix_ERR_class = ERRDOS; + unix_ERR_code = ERRinvalidname; + unix_ERR_ntstatus = NT_STATUS_NOT_A_DIRECTORY; + return NULL; + } + if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) { DEBUG(2,("open_directory: unable to create %s. Error was %s\n", fname, strerror(errno) )); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index ee47485126..26c107e17a 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3005,6 +3005,10 @@ NTSTATUS mkdir_internal(connection_struct *conn, pstring directory) unix_convert(directory,conn,0,&bad_path,&sbuf); + if( strchr_m(directory, ':')) { + return NT_STATUS_NOT_A_DIRECTORY; + } + if (ms_has_wild(directory)) { return NT_STATUS_OBJECT_NAME_INVALID; } -- cgit From 4568c8bb228663c59b09d82fa5052b8eea32c465 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2004 01:45:56 +0000 Subject: Ensure '.' and '..' don't match in delete requests. Jeremy. (This used to be commit c85b617aa03c1524f659100030a8e96cef38fb62) --- source3/smbd/reply.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 26c107e17a..0fe3be0752 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1449,7 +1449,10 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) while ((dname = ReadDirName(dirptr))) { pstring fname; pstrcpy(fname,dname); - + + if((strcmp(fname, ".") == 0) || (strcmp(fname, "..")==0)) + continue; + if(!mask_match(fname, mask, case_sensitive)) continue; -- cgit From 4fed0f2749ca8fc579a18f38099a370ac243caec Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Feb 2004 15:46:18 +0000 Subject: 'net idmap restore' is too useful to be left broken :-) Set the HWM values correctly after having manipulated the tdb. Volker (This used to be commit efad125f40858176145c69265d06b25295292132) --- source3/utils/net_idmap.c | 106 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c index b035d8d2f1..61ef919b84 100644 --- a/source3/utils/net_idmap.c +++ b/source3/utils/net_idmap.c @@ -70,6 +70,109 @@ static int net_idmap_dump(int argc, const char **argv) return 0; } +/*********************************************************** + Fix up the HWMs after a idmap restore. + **********************************************************/ + +struct hwms { + BOOL ok; + int user_hwm; + int group_hwm; +}; + +static int net_idmap_find_max_id(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, + void *handle) +{ + struct hwms *hwms = (struct hwms *)handle; + int *idptr = NULL; + int id; + + if (strncmp(key.dptr, "S-", 2) != 0) + return 0; + + if (sscanf(data.dptr, "GID %d", &id) == 1) { + idptr = &hwms->group_hwm; + } + + if (sscanf(data.dptr, "UID %d", &id) == 1) { + idptr = &hwms->user_hwm; + } + + if (idptr == NULL) { + d_printf("Illegal idmap entry: [%s]->[%s]\n", + key.dptr, data.dptr); + hwms->ok = False; + return -1; + } + + if (*idptr <= id) + *idptr = id+1; + + return 0; +} + +static NTSTATUS net_idmap_fixup_hwm(void) +{ + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + TDB_CONTEXT *idmap_tdb; + char *tdbfile = NULL; + int dummy; + + struct hwms hwms; + struct hwms highest; + + if (!lp_idmap_uid(&hwms.user_hwm, &highest.user_hwm) || + !lp_idmap_gid(&hwms.group_hwm, &highest.group_hwm)) { + d_printf("idmap range missing\n"); + return NT_STATUS_UNSUCCESSFUL; + } + + tdbfile = strdup(lock_path("winbindd_idmap.tdb")); + if (!tdbfile) { + DEBUG(0, ("idmap_init: out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } + + idmap_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0); + + if (idmap_tdb == NULL) { + d_printf("Could not open idmap: %s\n", tdbfile); + return NT_STATUS_NO_SUCH_FILE; + } + + hwms.ok = True; + + tdb_traverse(idmap_tdb, net_idmap_find_max_id, &hwms); + + if (!hwms.ok) { + goto done; + } + + d_printf("USER HWM: %d GROUP HWM: %d\n", + hwms.user_hwm, hwms.group_hwm); + + if (hwms.user_hwm >= highest.user_hwm) { + d_printf("Highest UID out of uid range\n"); + goto done; + } + + if (hwms.group_hwm >= highest.group_hwm) { + d_printf("Highest GID out of gid range\n"); + goto done; + } + + if ((tdb_store_int32(idmap_tdb, "USER HWM", hwms.user_hwm) != 0) || + (tdb_store_int32(idmap_tdb, "GROUP HWM", hwms.group_hwm) != 0)) { + d_printf("Could not store HWMs\n"); + goto done; + } + + result = NT_STATUS_OK; + done: + tdb_close(idmap_tdb); + return result; +} + /*********************************************************** Write entries from stdin to current local idmap **********************************************************/ @@ -129,7 +232,8 @@ static int net_idmap_restore(int argc, const char **argv) } idmap_close(); - return 0; + + return NT_STATUS_IS_OK(net_idmap_fixup_hwm()) ? 0 : -1; } int net_help_idmap(int argc, const char **argv) -- cgit From ce789de6e1aa8c8e024edbb0ad4c3411cb0649ef Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Feb 2004 17:29:06 +0000 Subject: Remove unused variable. Volker (This used to be commit f5af0326e67c0eb7be6f4b07f8b89c4c680903ac) --- source3/utils/net_idmap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c index 61ef919b84..f5b4bf1b4a 100644 --- a/source3/utils/net_idmap.c +++ b/source3/utils/net_idmap.c @@ -116,7 +116,6 @@ static NTSTATUS net_idmap_fixup_hwm(void) NTSTATUS result = NT_STATUS_UNSUCCESSFUL; TDB_CONTEXT *idmap_tdb; char *tdbfile = NULL; - int dummy; struct hwms hwms; struct hwms highest; -- cgit From c09049d25b22d843524ba54ceeb69295487b2de6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Feb 2004 18:03:19 +0000 Subject: Add 'net rpc group add'. For this parse_samr.c had to be changed: The group_info4 in set_dom_group_info also has the level in the record itself. This seems not to be an align. Tested with NT4 usrmgr.exe. It can still create a domain group on a samba machine. Volker (This used to be commit 9cadd14aa53d390a2419d7ce4fe48d58cf372279) --- source3/include/mapping.h | 7 ++++ source3/include/rpc_samr.h | 1 + source3/rpc_client/cli_samr.c | 93 ++++++++++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_samr.c | 8 ++-- source3/utils/net_rpc.c | 63 +++++++++++++++++++++++++++- 5 files changed, 167 insertions(+), 5 deletions(-) diff --git a/source3/include/mapping.h b/source3/include/mapping.h index fdaa2b0453..cd213cfc11 100644 --- a/source3/include/mapping.h +++ b/source3/include/mapping.h @@ -29,5 +29,12 @@ typedef struct _GROUP_MAP { enum SID_NAME_USE sid_name_use; fstring nt_name; fstring comment; + + /* Here we store SIDs that we can be sure of to be of type + * SID_NAME_DOM_GRP, so it's a Domain Group which can not be + * represented via /etc/group memberships. */ + + int num_member; + DOM_SID *alias_members; } GROUP_MAP; diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index a8ca504c8f..111e62c355 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -1076,6 +1076,7 @@ typedef struct samr_group_info3 typedef struct samr_group_info4 { + uint16 level; UNIHDR hdr_acct_desc; UNISTR2 uni_acct_desc; diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 38d2119e83..c924e33f8a 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -322,6 +322,55 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Create domain group */ + +NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, + const char *group_name, + uint32 access_mask, POLICY_HND *group_pol) +{ + prs_struct qbuf, rbuf; + SAMR_Q_CREATE_DOM_GROUP q; + SAMR_R_CREATE_DOM_GROUP r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + DEBUG(10,("cli_samr_create_dom_group\n")); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_create_dom_group(&q, domain_pol, group_name, access_mask); + + if (!samr_io_q_create_dom_group("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_CREATE_DOM_GROUP, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!samr_io_r_create_dom_group("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (NT_STATUS_IS_OK(result)) + *group_pol = r.pol; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Query user info */ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, @@ -368,6 +417,50 @@ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Set group info */ + +NTSTATUS cli_samr_set_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, GROUP_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_SET_GROUPINFO q; + SAMR_R_SET_GROUPINFO r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + DEBUG(10,("cli_samr_set_groupinfo\n")); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_set_groupinfo(&q, group_pol, ctr); + + if (!samr_io_q_set_groupinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_SET_GROUPINFO, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!samr_io_r_set_groupinfo("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Query group info */ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index d6f371d471..402f23bde8 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -2271,10 +2271,11 @@ BOOL samr_io_group_info3(const char *desc, GROUP_INFO3 *gr3, prs_struct *ps, int inits a GROUP_INFO4 structure. ********************************************************************/ -void init_samr_group_info4(GROUP_INFO4 * gr4, char *acct_desc) +void init_samr_group_info4(GROUP_INFO4 * gr4, const char *acct_desc) { DEBUG(5, ("init_samr_group_info4\n")); + gr4->level = 4; init_unistr2(&gr4->uni_acct_desc, acct_desc, UNI_FLAGS_NONE); init_uni_hdr(&gr4->hdr_acct_desc, &gr4->uni_acct_desc); } @@ -2292,9 +2293,8 @@ BOOL samr_io_group_info4(const char *desc, GROUP_INFO4 * gr4, prs_debug(ps, depth, desc, "samr_io_group_info4"); depth++; - if(!prs_align(ps)) + if(!prs_uint16("hdr_level", ps, depth, &gr4->level)) return False; - if(!smb_io_unihdr("hdr_acct_desc", &gr4->hdr_acct_desc, ps, depth)) return False; if(!smb_io_unistr2("uni_acct_desc", &gr4->uni_acct_desc, @@ -2349,7 +2349,7 @@ inits a SAMR_Q_CREATE_DOM_GROUP structure. ********************************************************************/ void init_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP * q_e, - POLICY_HND *pol, char *acct_desc, + POLICY_HND *pol, const char *acct_desc, uint32 access_mask) { DEBUG(5, ("init_samr_q_create_dom_group\n")); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index de6c8be900..e46dfe7fd4 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1044,6 +1044,67 @@ static int rpc_group_usage(int argc, const char **argv) return net_help_group(argc, argv); } +static NTSTATUS +rpc_group_add_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + POLICY_HND connect_pol, domain_pol, group_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + GROUP_INFO_CTR group_info; + + if (argc != 1) { + d_printf("Group name must be specified\n"); + rpc_group_usage(argc, argv); + return NT_STATUS_OK; + } + + /* Get sam policy handle */ + + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) goto done; + + /* Get domain policy handle */ + + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + domain_sid, &domain_pol); + if (!NT_STATUS_IS_OK(result)) goto done; + + /* Create the group */ + + result = cli_samr_create_dom_group(cli, mem_ctx, &domain_pol, + argv[0], MAXIMUM_ALLOWED_ACCESS, + &group_pol); + if (!NT_STATUS_IS_OK(result)) goto done; + + if (strlen(opt_comment) == 0) goto done; + + /* We've got a comment to set */ + + group_info.switch_value1 = 4; + init_samr_group_info4(&group_info.group.info4, opt_comment); + + result = cli_samr_set_groupinfo(cli, mem_ctx, &group_pol, &group_info); + if (!NT_STATUS_IS_OK(result)) goto done; + + done: + if (NT_STATUS_IS_OK(result)) + DEBUG(5, ("add group succeeded\n")); + else + d_printf("add group failed: %s\n", nt_errstr(result)); + + return result; +} + +static int rpc_group_add(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_SAMR, 0, + rpc_group_add_internals, + argc, argv); +} + /** * List groups on a remote RPC server * @@ -1498,8 +1559,8 @@ static int rpc_group_members(int argc, const char **argv) int net_rpc_group(int argc, const char **argv) { struct functable func[] = { -#if 0 {"add", rpc_group_add}, +#if 0 {"delete", rpc_group_delete}, #endif {"list", rpc_group_list}, -- cgit From 7b51df1e5400a188b7f3d69b973774d35c952d27 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2004 00:48:17 +0000 Subject: More gentest fixes. Jeremy. (This used to be commit fc9811693933327a15b7dbe4893219c7ef44d1e8) --- source3/smbd/reply.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 0fe3be0752..d0888fc682 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1309,7 +1309,7 @@ static NTSTATUS can_rename(char *fname,connection_struct *conn, SMB_STRUCT_STAT Check if a user is allowed to delete a file. ********************************************************************/ -static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype) +static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype, BOOL bad_path) { SMB_STRUCT_STAT sbuf; int fmode; @@ -1323,8 +1323,15 @@ static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype) if (!CAN_WRITE(conn)) return NT_STATUS_MEDIA_WRITE_PROTECTED; - if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) { + if(errno == ENOENT) { + if (bad_path) + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + else + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + return map_nt_error_from_unix(errno); + } fmode = dos_mode(conn,fname,&sbuf); @@ -1421,7 +1428,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) if (!has_wild) { pstrcat(directory,"/"); pstrcat(directory,mask); - error = can_delete(directory,conn,dirtype); + error = can_delete(directory,conn,dirtype,bad_path); if (!NT_STATUS_IS_OK(error)) return error; @@ -1457,7 +1464,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) continue; slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); - error = can_delete(fname,conn,dirtype); + error = can_delete(fname,conn,dirtype,bad_path); if (!NT_STATUS_IS_OK(error)) continue; if (SMB_VFS_UNLINK(conn,fname) == 0) @@ -3639,7 +3646,8 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", dirptr = OpenDir(conn, directory, True); if (dirptr) { - error = NT_STATUS_OBJECT_NAME_NOT_FOUND; + error = NT_STATUS_NO_SUCH_FILE; +/* Was error = NT_STATUS_OBJECT_NAME_NOT_FOUND; - gentest fix. JRA */ if (strequal(mask,"????????.???")) pstrcpy(mask,"*"); @@ -3649,6 +3657,9 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", pstrcpy(fname,dname); + if((strcmp(fname, ".") == 0) || (strcmp(fname, "..")==0)) + continue; + if(!mask_match(fname, mask, case_sensitive)) continue; -- cgit From 8d596105ad39a8af7b41eb3442ce80ecbb301573 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2004 01:34:58 +0000 Subject: More gentest fun :-). NB. I'm not fixing OpenX breakage 'cos if you look at what W2K3 accepts here it's COMPLETELY BROKEN ! :-). Jeremy. (This used to be commit 9aa37cb84090260b33d32ad123ddc4d211e3913b) --- source3/smbd/reply.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index d0888fc682..c729f22728 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1457,8 +1457,12 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) pstring fname; pstrcpy(fname,dname); - if((strcmp(fname, ".") == 0) || (strcmp(fname, "..")==0)) - continue; + /* Quick check for "." and ".." */ + if (fname[0] == '.') { + if (!fname[1] || (fname[1] == '.' && !fname[2])) { + continue; + } + } if(!mask_match(fname, mask, case_sensitive)) continue; @@ -3357,6 +3361,13 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char * ZERO_STRUCT(sbuf); unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf); + /* Quick check for "." and ".." */ + if (newname_last_component[0] == '.') { + if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { + return NT_STATUS_ACCESS_DENIED; + } + } + /* Ensure newname contains a '/' */ if(strrchr_m(newname,'/') == 0) { pstring tmpstr; @@ -3470,6 +3481,13 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BO rc = unix_convert(name,conn,0,&bad_path1,&sbuf1); unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2); + /* Quick check for "." and ".." */ + if (newname_last_component[0] == '.') { + if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { + return NT_STATUS_ACCESS_DENIED; + } + } + /* * Split the old name into directory and last component * strings. Note that unix_convert may have stripped off a @@ -3478,7 +3496,7 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BO * name and newname contain a / character or neither of them do * as this is checked in resolve_wildcards(). */ - + p = strrchr_m(name,'/'); if (!p) { pstrcpy(directory,"."); @@ -3657,8 +3675,12 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", pstrcpy(fname,dname); - if((strcmp(fname, ".") == 0) || (strcmp(fname, "..")==0)) - continue; + /* Quick check for "." and ".." */ + if (fname[0] == '.') { + if (!fname[1] || (fname[1] == '.' && !fname[2])) { + continue; + } + } if(!mask_match(fname, mask, case_sensitive)) continue; -- cgit From 538633b0f8da19687b16df3d7d424227a2e0fd90 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2004 02:15:20 +0000 Subject: Figured out a new flags bit with gentest and ethereal.... Jeremy. (This used to be commit 755b66303d04b73a855fa8db5fe3ae920a901bf3) --- source3/include/smb.h | 1 + source3/smbd/nttrans.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/source3/include/smb.h b/source3/include/smb.h index 1bf5db4768..5cd5e71f74 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1087,6 +1087,7 @@ struct bitmap { #define REQUEST_OPLOCK 2 #define REQUEST_BATCH_OPLOCK 4 #define OPEN_DIRECTORY 8 +#define EXTENDED_RESPONSE_REQUIRED 0x10 /* ShareAccess field. */ #define FILE_SHARE_NONE 0 /* Cannot be used in bitmask. */ diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 4e87f191d8..a8a314c876 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -975,9 +975,12 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib SOFF_T(p, 0, get_allocation_size(fsp,&sbuf)); p += 8; SOFF_T(p,0,file_len); - p += 12; + p += 8; + if (flags & EXTENDED_RESPONSE_REQUIRED) + SSVAL(p,2,0x7); + p += 4; SCVAL(p,0,fsp->is_directory ? 1 : 0); - + DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name)); result = chain_reply(inbuf,outbuf,length,bufsize); @@ -1455,6 +1458,11 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o SOFF_T(p, 0, get_allocation_size(fsp,&sbuf)); p += 8; SOFF_T(p,0,file_len); + p += 8; + if (flags & EXTENDED_RESPONSE_REQUIRED) + SSVAL(p,2,0x7); + p += 4; + SCVAL(p,0,fsp->is_directory ? 1 : 0); DEBUG(5,("call_nt_transact_create: open name = %s\n", fname)); -- cgit From f6b68d962f15c464f3ade953b4651f33733cfd2f Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 25 Feb 2004 15:01:38 +0000 Subject: reset time and duration are set in minutes, not seconds. Works from usrmgr. (This used to be commit 08a7c9697d49719e4cfb32a06720873c98585f67) --- source3/rpc_server/srv_samr_nt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index a087e28f09..10069abb76 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -4502,8 +4502,8 @@ NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R case 0x07: break; case 0x0c: - u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration); - u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count); + u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60; + u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60; account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration); account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time); -- cgit From 4b6cb540de9dc04d3329062513895976f4214004 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 25 Feb 2004 20:02:41 +0000 Subject: Do the query part of the previous fix...reset time and duration are set in minutes, not seconds. Works from usrmgr. (This used to be commit d02dd0e5f5fae3256b1922c2963e18c8fa36a3e6) --- source3/rpc_server/srv_samr_nt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 10069abb76..58dcd48d8d 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2081,10 +2081,10 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA break; case 0x0c: account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp); - u_lock_duration = account_policy_temp; + u_lock_duration = account_policy_temp * 60; account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp); - u_reset_time = account_policy_temp; + u_reset_time = account_policy_temp * 60; account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp); lockout = account_policy_temp; -- cgit From 3f67bb3a69f7a1631e2e158f4d58095c88f6bbb2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Feb 2004 21:37:09 +0000 Subject: Fixup strange rename error case (gentest). Jeremy. (This used to be commit e46aaffe97919afb1c92f56376f9578825012b92) --- source3/smbd/reply.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c729f22728..49f4e97028 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3482,8 +3482,9 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BO unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2); /* Quick check for "." and ".." */ - if (newname_last_component[0] == '.') { + if (!bad_path2 && newname_last_component[0] == '.') { if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { + DEBUG(10,("rename_internals: newname_last_component = '.' or '..'\n")); return NT_STATUS_ACCESS_DENIED; } } -- cgit From ebd86253c6bfb8ccb01e23c7e0446802e9009825 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Feb 2004 22:09:46 +0000 Subject: (merge from 3.0) I *hate* global variables... OK, what was happening here was that we would invalidate global_sam_sid when we set the sid into secrets.tdb, to force a re-read. The problem was, we would do *two* writes into the TDB, and the second one (in the PDC/BDC case) would be of a NULL pointer. This caused smbd startups to fail, on a blank TDB. By using a local variable in the pdb_generate_sam_sid() code, we avoid this particular trap. I've also added better debugging for the case where this all matters, which is particularly for LDAP, where it finds out a domain SID from the sambaDomain object. Andrew Bartlett (This used to be commit f3ecdea56d9ea6d562ace84f0e653a641eb96f6e) --- source3/passdb/machine_sid.c | 67 ++++++++++++++++++++++++-------------------- source3/passdb/pdb_ldap.c | 9 +++++- source3/utils/net.c | 10 +++++++ source3/utils/smbpasswd.c | 6 ++++ 4 files changed, 61 insertions(+), 31 deletions(-) diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c index 21ae95af5b..235187abf0 100644 --- a/source3/passdb/machine_sid.c +++ b/source3/passdb/machine_sid.c @@ -76,15 +76,15 @@ static void generate_random_sid(DOM_SID *sid) Generate the global machine sid. ****************************************************************************/ -static BOOL pdb_generate_sam_sid(void) +static DOM_SID *pdb_generate_sam_sid(void) { DOM_SID domain_sid; char *fname = NULL; BOOL is_dc = False; - - if(global_sam_sid==NULL) - if(!(global_sam_sid=(DOM_SID *)malloc(sizeof(DOM_SID)))) - return False; + DOM_SID *sam_sid; + + if(!(sam_sid=(DOM_SID *)malloc(sizeof(DOM_SID)))) + return NULL; generate_wellknown_sids(); @@ -100,86 +100,93 @@ static BOOL pdb_generate_sam_sid(void) if (is_dc) { if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { - sid_copy(global_sam_sid, &domain_sid); - return True; + sid_copy(sam_sid, &domain_sid); + return sam_sid; } } - if (secrets_fetch_domain_sid(global_myname(), global_sam_sid)) { + if (secrets_fetch_domain_sid(global_myname(), sam_sid)) { /* We got our sid. If not a pdc/bdc, we're done. */ if (!is_dc) - return True; + return sam_sid; if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { /* No domain sid and we're a pdc/bdc. Store it */ - if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { + if (!secrets_store_domain_sid(lp_workgroup(), sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Can't store domain SID as a pdc/bdc.\n")); - return False; + SAFE_FREE(sam_sid); + return NULL; } - return True; + return sam_sid; } - if (!sid_equal(&domain_sid, global_sam_sid)) { + if (!sid_equal(&domain_sid, sam_sid)) { /* Domain name sid doesn't match global sam sid. Re-store domain sid as 'local' sid. */ DEBUG(0,("pdb_generate_sam_sid: Mismatched SIDs as a pdc/bdc.\n")); if (!secrets_store_domain_sid(global_myname(), &domain_sid)) { DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID for local sid as PDC/BDC.\n")); - return False; + SAFE_FREE(sam_sid); + return NULL; } - return True; + return sam_sid; } - return True; + return sam_sid; } /* check for an old MACHINE.SID file for backwards compatibility */ asprintf(&fname, "%s/MACHINE.SID", lp_private_dir()); - if (read_sid_from_file(fname, global_sam_sid)) { + if (read_sid_from_file(fname, sam_sid)) { /* remember it for future reference and unlink the old MACHINE.SID */ - if (!secrets_store_domain_sid(global_myname(), global_sam_sid)) { + if (!secrets_store_domain_sid(global_myname(), sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Failed to store SID from file.\n")); SAFE_FREE(fname); - return False; + SAFE_FREE(sam_sid); + return NULL; } unlink(fname); if (is_dc) { - if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { + if (!secrets_store_domain_sid(lp_workgroup(), sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Failed to store domain SID from file.\n")); SAFE_FREE(fname); - return False; + SAFE_FREE(sam_sid); + return NULL; } } /* Stored the old sid from MACHINE.SID successfully.*/ SAFE_FREE(fname); - return True; + SAFE_FREE(sam_sid); + return sam_sid; } SAFE_FREE(fname); /* we don't have the SID in secrets.tdb, we will need to generate one and save it */ - generate_random_sid(global_sam_sid); + generate_random_sid(sam_sid); - if (!secrets_store_domain_sid(global_myname(), global_sam_sid)) { + if (!secrets_store_domain_sid(global_myname(), sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Failed to store generated machine SID.\n")); - return False; + SAFE_FREE(sam_sid); + return NULL; } if (is_dc) { - if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { + if (!secrets_store_domain_sid(lp_workgroup(), sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Failed to store generated domain SID.\n")); - return False; + SAFE_FREE(sam_sid); + return NULL; } } - return True; + return sam_sid; } /* return our global_sam_sid */ @@ -191,10 +198,10 @@ DOM_SID *get_global_sam_sid(void) /* memory for global_sam_sid is allocated in pdb_generate_sam_sid() as needed */ - if (!pdb_generate_sam_sid()) { + if (!(global_sam_sid = pdb_generate_sam_sid())) { smb_panic("Could not generate a machine SID\n"); } - + return global_sam_sid; } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 3db0702c92..eefd302d42 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -2353,7 +2353,7 @@ static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_met /* Try to setup the Domain Name, Domain SID, algorithmic rid base */ nt_status = smbldap_search_domain_info(ldap_state->smbldap_state, &result, - ldap_state->domain_name, True); + ldap_state->domain_name, True); if ( !NT_STATUS_IS_OK(nt_status) ) { DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain info, nor add one to the domain\n")); @@ -2382,8 +2382,15 @@ and will risk BDCs having inconsistant SIDs\n")); } found_sid = secrets_fetch_domain_sid(ldap_state->domain_name, &secrets_domain_sid); if (!found_sid || !sid_equal(&secrets_domain_sid, &ldap_domain_sid)) { + fstring new_sid_str, old_sid_str; + DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain %s based on pdb_ldap results %s -> %s\n", + ldap_state->domain_name, + sid_to_string(old_sid_str, &secrets_domain_sid), + sid_to_string(new_sid_str, &ldap_domain_sid))); + /* reset secrets.tdb sid */ secrets_store_domain_sid(ldap_state->domain_name, &ldap_domain_sid); + DEBUG(1, ("New global sam SID: %s\n", sid_to_string(new_sid_str, get_global_sam_sid()))); } sid_copy(&ldap_state->domain_sid, &ldap_domain_sid); } diff --git a/source3/utils/net.c b/source3/utils/net.c index b9081c3e31..9026900e81 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -418,6 +418,11 @@ static int net_getlocalsid(int argc, const char **argv) name = global_myname(); } + if(!initialize_password_db(False)) { + DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n" + "backend knowlege (such as the sid stored in LDAP)\n")); + } + if (!secrets_fetch_domain_sid(name, &sid)) { DEBUG(0, ("Can't fetch domain SID for name: %s\n", name)); return 1; @@ -452,6 +457,11 @@ static int net_getdomainsid(int argc, const char **argv) DOM_SID domain_sid; fstring sid_str; + if(!initialize_password_db(False)) { + DEBUG(0, ("WARNING: Could not open passdb - domain sid may not reflect passdb\n" + "backend knowlege (such as the sid stored in LDAP)\n")); + } + if (!secrets_fetch_domain_sid(global_myname(), &domain_sid)) { d_printf("Could not fetch local SID\n"); return 1; diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index ea8bf7a472..5507727498 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -348,6 +348,12 @@ static int process_root(int local_flags) goto done; } + /* Ensure passdb startup(). */ + if(!initialize_password_db(False)) { + DEBUG(0, ("Failed to open passdb!\n")); + exit(1); + } + /* Ensure we have a SAM sid. */ get_global_sam_sid(); -- cgit From eb8ed992c65a4d394d40ef21002c366ce501c7e4 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 25 Feb 2004 22:14:35 +0000 Subject: Adds some more tests of renaming an open file that has been opened with different share modes. It also has a commented out test to see if we can actually open a renamed file, and it turns out that we can, it seems. I am not sure at this stage how long that is the case for, though. (This used to be commit 89d810d234f53c9731ded85848bd9c17d45d5125) --- source3/torture/torture.c | 83 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 57ba24e63e..9947e22c4f 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -3326,7 +3326,7 @@ static BOOL run_rename(int dummy) const char *fname = "\\test.txt"; const char *fname1 = "\\test1.txt"; BOOL correct = True; - int fnum1; + int fnum1, fnum2; printf("starting rename test\n"); @@ -3345,9 +3345,9 @@ static BOOL run_rename(int dummy) } if (!cli_rename(cli1, fname, fname1)) { - printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1)); + printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1)); } else { - printf("First rename succeeded - this should have failed !\n"); + printf("First rename succeeded (SHARE_READ) - this should have failed !\n"); correct = False; } @@ -3371,10 +3371,10 @@ static BOOL run_rename(int dummy) } if (!cli_rename(cli1, fname, fname1)) { - printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1)); + printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1)); correct = False; } else { - printf("Second rename succeeded\n"); + printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n"); } if (!cli_close(cli1, fnum1)) { @@ -3418,10 +3418,10 @@ static BOOL run_rename(int dummy) #endif if (!cli_rename(cli1, fname, fname1)) { - printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1)); + printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1)); correct = False; } else { - printf("Third rename succeeded\n"); + printf("Third rename succeeded (SHARE_NONE)\n"); } if (!cli_close(cli1, fnum1)) { @@ -3432,6 +3432,75 @@ static BOOL run_rename(int dummy) cli_unlink(cli1, fname); cli_unlink(cli1, fname1); + /*----*/ + + fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0); + + if (fnum1 == -1) { + printf("Fourth open failed - %s\n", cli_errstr(cli1)); + return False; + } + + if (!cli_rename(cli1, fname, fname1)) { + printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1)); + } else { + printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n"); + correct = False; + } + + if (!cli_close(cli1, fnum1)) { + printf("close - 4 failed (%s)\n", cli_errstr(cli1)); + return False; + } + + cli_unlink(cli1, fname); + cli_unlink(cli1, fname1); + + /*--*/ + + fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0); + + if (fnum1 == -1) { + printf("Fifth open failed - %s\n", cli_errstr(cli1)); + return False; + } + + if (!cli_rename(cli1, fname, fname1)) { + printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have failed ! \n"); + correct = False; + } else { + printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1)); + } + + /* + * Now check if the first name still exists ... + */ + + /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0); + + if (fnum2 == -1) { + printf("Opening original file after rename of open file fails: %s\n", + cli_errstr(cli1)); + } + else { + printf("Opening original file after rename of open file works ...\n"); + (void)cli_close(cli1, fnum2); + } */ + + /*--*/ + + + if (!cli_close(cli1, fnum1)) { + printf("close - 5 failed (%s)\n", cli_errstr(cli1)); + return False; + } + + cli_unlink(cli1, fname); + cli_unlink(cli1, fname1); + if (!torture_close_connection(cli1)) { correct = False; } -- cgit From 41025e8d4f88eb024dbe4a130cf9eb0519b39158 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Feb 2004 23:19:17 +0000 Subject: (merge from 3.0) Fix bug in previous global_sam_sid() commit. I broke the 'read from MACHINE.SID' file functionality. Also, before we print out the results of 'net getlocalsid' and 'net getdomainsid', ensure we have tried to read that file, or have generated one. Andrew Bartlett (This used to be commit af1b6447b8292a83851361570219ee6d889e0898) --- source3/passdb/machine_sid.c | 1 - source3/utils/net.c | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c index 235187abf0..903f0ca5a1 100644 --- a/source3/passdb/machine_sid.c +++ b/source3/passdb/machine_sid.c @@ -163,7 +163,6 @@ static DOM_SID *pdb_generate_sam_sid(void) /* Stored the old sid from MACHINE.SID successfully.*/ SAFE_FREE(fname); - SAFE_FREE(sam_sid); return sam_sid; } diff --git a/source3/utils/net.c b/source3/utils/net.c index 9026900e81..01f56b8a0c 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -423,6 +423,9 @@ static int net_getlocalsid(int argc, const char **argv) "backend knowlege (such as the sid stored in LDAP)\n")); } + /* Generate one, if it doesn't exist */ + get_global_sam_sid(); + if (!secrets_fetch_domain_sid(name, &sid)) { DEBUG(0, ("Can't fetch domain SID for name: %s\n", name)); return 1; @@ -462,6 +465,9 @@ static int net_getdomainsid(int argc, const char **argv) "backend knowlege (such as the sid stored in LDAP)\n")); } + /* Generate one, if it doesn't exist */ + get_global_sam_sid(); + if (!secrets_fetch_domain_sid(global_myname(), &domain_sid)) { d_printf("Could not fetch local SID\n"); return 1; -- cgit From fb7a1848d17720a661910aaf7431807e820e0215 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Feb 2004 01:30:56 +0000 Subject: Interesting fact found by IFSTEST /t LockOverlappedTest... Even if it's our own lock context, we need to wait here as there may be an unlock on the way. So I removed a "&& !my_lock_ctx" from the following if statement. if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) { Jeremy. (This used to be commit 17c88758ae82b20bc7260d5d927325f3f73ba33c) --- source3/smbd/reply.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 49f4e97028..643b7c2d08 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -4357,7 +4357,14 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); status = do_lock_spin(fsp,conn,lock_pid, count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &my_lock_ctx); if (NT_STATUS_V(status)) { - if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) { + /* + * Interesting fact found by IFSTEST /t LockOverlappedTest... + * Even if it's our own lock context, we need to wait here as + * there may be an unlock on the way. + * So I removed a "&& !my_lock_ctx" from the following + * if statement. JRA. + */ + if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) { /* * A blocking lock was requested. Package up * this smb into a queued request and push it -- cgit From 12d5c14dd04d158cdd55f845156d8673a78e82db Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Feb 2004 10:56:41 +0000 Subject: Apply some const Volker (This used to be commit f1b66461ebce4e89eb65620a09c079ae9697537b) --- source3/libsmb/clirap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index f8204e05d6..98066629d1 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -206,8 +206,9 @@ The callback function takes 4 arguments: the machine name, the server type, the comment and a state pointer. ****************************************************************************/ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *, void *), - void *state) + void (*fn)(const char *, uint32, const char *, + const void *), + const void *state) { char *rparam = NULL; char *rdata = NULL; -- cgit From 92f97426bea2745955c9c8924362a520c165f266 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Feb 2004 11:08:17 +0000 Subject: And another little const (This used to be commit a3a15be5a2ae419992af004425592cca6796edcd) --- source3/passdb/pdb_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 5b97c5fbad..581fac364a 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -893,7 +893,7 @@ BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid) pdb_getgrgid(pdb_context, map, gid)); } -BOOL pdb_getgrnam(GROUP_MAP *map, char *name) +BOOL pdb_getgrnam(GROUP_MAP *map, const char *name) { struct pdb_context *pdb_context = pdb_get_static_context(False); -- cgit From 688ea97ba09607279eef1cc3739b47d299c702ba Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Feb 2004 11:34:33 +0000 Subject: Implement 'net groupmap set' and 'net groupmap cleanup'. I was rather annoyed by the net groupmap syntax, I could never get it right. net groupmap set "domain admins" domadm creates a mapping, net groupmap set "domain admins" -C "Comment" -N "newntname" should also do what you expect. net groupmap cleanup solves a problem I've had two times now: Our SID changed, and a user's primary group was mapped to a SID that is not ours. net groupmap cleanup removes all mappings that are not from our domain sid. Volker (This used to be commit 69879ceffa587ccf2bf59e1c716424e1d20a7f68) --- source3/utils/net.c | 11 ++++ source3/utils/net.h | 5 ++ source3/utils/net_groupmap.c | 141 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+) diff --git a/source3/utils/net.c b/source3/utils/net.c index 01f56b8a0c..8004ced43e 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -73,6 +73,10 @@ int opt_flags = -1; int opt_timeout = 0; const char *opt_target_workgroup = NULL; int opt_machine_pass = 0; +BOOL opt_localgroup = False; +BOOL opt_domaingroup = False; +const char *opt_newntname = ""; +int opt_rid = 0; BOOL opt_have_ip = False; struct in_addr opt_dest_ip; @@ -680,6 +684,13 @@ static struct functable net_func[] = { {"timeout", 't', POPT_ARG_INT, &opt_timeout}, {"machine-pass",'P', POPT_ARG_NONE, &opt_machine_pass}, {"myworkgroup", 'W', POPT_ARG_STRING, &opt_workgroup}, + + /* Options for 'net groupmap set' */ + {"local", 'L', POPT_ARG_NONE, &opt_localgroup}, + {"domain", 'D', POPT_ARG_NONE, &opt_domaingroup}, + {"ntname", 'N', POPT_ARG_STRING, &opt_newntname}, + {"rid", 'R', POPT_ARG_INT, &opt_rid}, + POPT_COMMON_SAMBA { 0, 0, 0, 0} }; diff --git a/source3/utils/net.h b/source3/utils/net.h index 94e6de9d18..62d5a74237 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -57,6 +57,11 @@ extern const char *opt_user_name; extern const char *opt_password; extern BOOL opt_user_specified; +extern BOOL opt_localgroup; +extern BOOL opt_domaingroup; +extern const char *opt_newntname; +extern int opt_rid; + extern BOOL opt_have_ip; extern struct in_addr opt_dest_ip; diff --git a/source3/utils/net_groupmap.c b/source3/utils/net_groupmap.c index 416f42507d..2b487ef17b 100644 --- a/source3/utils/net_groupmap.c +++ b/source3/utils/net_groupmap.c @@ -473,6 +473,141 @@ static int net_groupmap_delete(int argc, const char **argv) return 0; } +static int net_groupmap_set(int argc, const char **argv) +{ + const char *ntgroup = NULL; + struct group *grp = NULL; + GROUP_MAP map; + BOOL have_map = False; + + if ((argc < 1) || (argc > 2)) { + d_printf("Usage: net groupmap set \"NT Group\" " + "[\"unix group\"] [-C \"comment\"] [-L] [-D]\n"); + return -1; + } + + if ( opt_localgroup && opt_domaingroup ) { + d_printf("Can only specify -L or -D, not both\n"); + return -1; + } + + ntgroup = argv[0]; + + if (argc == 2) { + grp = getgrnam(argv[1]); + + if (grp == NULL) { + d_printf("Could not find unix group %s\n", argv[1]); + return -1; + } + } + + have_map = pdb_getgrnam(&map, ntgroup); + + if (!have_map) { + DOM_SID sid; + have_map = ( (strncmp(ntgroup, "S-", 2) == 0) && + string_to_sid(&sid, ntgroup) && + pdb_getgrsid(&map, sid) ); + } + + if (!have_map) { + + /* Ok, add it */ + + if (grp == NULL) { + d_printf("Could not find group mapping for %s\n", + ntgroup); + return -1; + } + + map.gid = grp->gr_gid; + + if (opt_rid == 0) { + opt_rid = pdb_gid_to_group_rid(map.gid); + } + + sid_copy(&map.sid, get_global_sam_sid()); + sid_append_rid(&map.sid, opt_rid); + + map.sid_name_use = SID_NAME_DOM_GRP; + fstrcpy(map.nt_name, ntgroup); + fstrcpy(map.comment, ""); + + if (!pdb_add_group_mapping_entry(&map)) { + d_printf("Could not add mapping entry for %s\n", + ntgroup); + return -1; + } + } + + /* Now we have a mapping entry, update that stuff */ + + if ( opt_localgroup || opt_domaingroup ) { + if (map.sid_name_use == SID_NAME_WKN_GRP) { + d_printf("Can't change type of the BUILTIN group %s\n", + map.nt_name); + return -1; + } + } + + if (opt_localgroup) + map.sid_name_use = SID_NAME_ALIAS; + + if (opt_domaingroup) + map.sid_name_use = SID_NAME_DOM_GRP; + + /* The case (opt_domaingroup && opt_localgroup) was tested for above */ + + if (strlen(opt_comment) > 0) + fstrcpy(map.comment, opt_comment); + + if (strlen(opt_newntname) > 0) + fstrcpy(map.nt_name, opt_newntname); + + if (grp != NULL) + map.gid = grp->gr_gid; + + if (!pdb_update_group_mapping_entry(&map)) { + d_printf("Could not update group mapping for %s\n", ntgroup); + return -1; + } + + return 0; +} + +static int net_groupmap_cleanup(int argc, const char **argv) +{ + GROUP_MAP *map = NULL; + int i, entries; + + if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &entries, + ENUM_ALL_MAPPED)) { + d_printf("Could not list group mappings\n"); + return -1; + } + + for (i=0; i Date: Thu, 26 Feb 2004 14:36:28 +0000 Subject: That const was one too many (This used to be commit b9ae67a3a232875361d3056eef3b654e6b92c244) --- source3/libsmb/clirap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 98066629d1..f8204e05d6 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -206,9 +206,8 @@ The callback function takes 4 arguments: the machine name, the server type, the comment and a state pointer. ****************************************************************************/ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *, - const void *), - const void *state) + void (*fn)(const char *, uint32, const char *, void *), + void *state) { char *rparam = NULL; char *rdata = NULL; -- cgit From e9f51e2ea9442c28a5fed0e931d6d4920dbd517d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 26 Feb 2004 22:58:18 +0000 Subject: Fix for writable printerdata problem - bugzilla #1112. (This used to be commit 892b16404033bbaf72a5a04f558cb41ef544739e) --- source3/python/samba/printerdata.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source3/python/samba/printerdata.py b/source3/python/samba/printerdata.py index 33251f6a00..0b53a3dfb5 100644 --- a/source3/python/samba/printerdata.py +++ b/source3/python/samba/printerdata.py @@ -15,8 +15,10 @@ from samba import spoolss class printerdata: - def __init__(self, host, creds = {}): - self.hnd = spoolss.openprinter(host, creds = creds) + def __init__(self, host, creds = {}, access = 0x02000000): + # For read access, use MAXIMUM_ALLOWED_ACCESS = 0x02000000 + # For write access, use PRINTER_ACCESS_ADMINISTER = 0x00000004 + self.hnd = spoolss.openprinter(host, creds = creds, access = access) def keys(self): return self.hnd.enumprinterdata().keys() @@ -30,10 +32,14 @@ class printerdata: "data": value}) class printerdata_ex: - def __init__(self, host): + def __init__(self, host, creds = {}, access = 0x02000000): + # For read access, use MAXIMUM_ALLOWED_ACCESS = 0x02000000 + # For write access, use PRINTER_ACCESS_ADMINISTER = 0x00000004 self.host = host self.top_level_keys = ["PrinterDriverData", "DsSpooler", "DsDriver", "DsUser"] + self.creds = creds + self.access = access def keys(self): return self.top_level_keys @@ -45,8 +51,8 @@ class printerdata_ex: return 0 class printerdata_ex_subkey: - def __init__(self, host, key): - self.hnd = spoolss.openprinter(host) + def __init__(self, host, key, creds, access): + self.hnd = spoolss.openprinter(host, creds, access) self.key = key def keys(self): @@ -56,4 +62,4 @@ class printerdata_ex: return self.hnd.getprinterdataex(self.key, key)['data'] def __getitem__(self, key): - return self.printerdata_ex_subkey(self.host, key) + return self.printerdata_ex_subkey(self.host, key, creds, access) -- cgit From 359ca5a5a58935ec1b651b70f1c343e36d6006b2 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Fri, 27 Feb 2004 20:00:21 +0000 Subject: Disabling GUMS (gums_tdbsam2) temporarily, to fix the build. rafal (This used to be commit 39bc55e4d407adb31030a57185f7431434b43a51) --- source3/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index 0dd5813527..fec57ee1f3 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -319,7 +319,7 @@ DYNEXP= dnl Add modules that have to be built by default here dnl These have to be built static: -default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_epmapper auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin pdb_gums gums_tdbsam2" +default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_epmapper auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin" dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap charset_CP850 charset_CP437" -- cgit From 9619eb610572363ed20ecee7cd03061789e3dc90 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Fri, 27 Feb 2004 21:02:00 +0000 Subject: Adding ability to operate on trust passwords to pdbedit. This enables new functionality and testing interface for new pdb functions. Also, quite a bit of objects is being added to pdbedit in order to make it able to find domain sid automatically (if not given explicitly). If such amount of "wisdom" is not required to be in pdbedit, I'll move it to 'net' which will have this new functionality, anyway. rafal (This used to be commit cfb1b7bda905c8391bf065ecb99bb28806dfe96a) --- source3/Makefile.in | 6 +- source3/utils/pdbedit.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 176 insertions(+), 6 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 886d9f81a9..25a0e45f05 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -449,9 +449,9 @@ SMBPASSWD_OBJ = utils/smbpasswd.o libsmb/passchange.o $(PARAM_OBJ) $(SECRETS_OBJ $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \ $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) lib/dummyroot.o -PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \ +PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) \ $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \ - $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o + $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(KRBCLIENT_OBJ) $(RPC_PARSE_OBJ) lib/dummyroot.o SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ) $(SECRETS_OBJ) @@ -876,7 +876,7 @@ bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(LDAP_LIBS) $(KRB5LIBS) bin/smbget@EXEEXT@: $(SMBGET_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 3f7aba8366..4178afdaf8 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -49,6 +49,10 @@ #define BIT_EXPORT 0x02000000 #define BIT_FIX_INIT 0x04000000 #define BIT_BADPWRESET 0x08000000 +#define BIT_TRUSTDOM 0x10000000 +#define BIT_TRUSTPW 0x20000000 +#define BIT_TRUSTSID 0x40000000 +#define BIT_TRUSTFLAGS 0x80000000 #define MASK_ALWAYS_GOOD 0x0000001F #define MASK_USER_GOOD 0x00401F00 @@ -538,6 +542,143 @@ static int new_machine (struct pdb_context *in, const char *machine_in) return 0; } + +/** + * Add new trusting domain account + * + * @param in initialised pdb_context + * @param dom_name trusted domain name given in command line + * + * @return 0 on success, -1 otherwise + **/ + +static int new_trustdom(struct pdb_context *in, const char *dom_name) +{ + /* TODO */ + return -1; +} + + +/** + * Add new trust relationship password + * + * @param in initialised pdb_context + * @param dom_name trusting domain name given in command line + * @param dom_sid domain sid given in command line + * @param flag trust password type flag given in command line + * + * @return 0 on success, -1 otherwise + **/ + +static int new_trustpw(struct pdb_context *in, const char *dom_name, + const char *dom_sid, const char* flag) +{ + const int flag_num = 5; + typedef struct { const char *name; int val; } flag_conv; + flag_conv flags[] = {{ "PASS_MACHINE_TRUST_NT", PASS_MACHINE_TRUST_NT }, + { "PASS_SERVER_TRUST_NT", PASS_SERVER_TRUST_NT }, + { "PASS_DOMAIN_TRUST_NT", PASS_DOMAIN_TRUST_NT }, + { "PASS_MACHINE_TRUST_ADS",PASS_MACHINE_TRUST_ADS }, + { "PASS_DOMAIN_TRUST_ADS", PASS_DOMAIN_TRUST_ADS }}; + + TALLOC_CTX *mem_ctx = NULL; + SAM_TRUST_PASSWD trust; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + POLICY_HND connect_hnd; + DOM_SID *domain_sid = NULL; + smb_ucs2_t *uni_name = NULL; + char *givenpass, *domain_name = NULL; + struct in_addr srv_ip; + fstring srv_name, myname; + struct cli_state *cli; + int i; + time_t lct; + + if (!dom_name) return -1; + + mem_ctx = talloc_init("pdbedit: adding new trust password"); + + /* unicode name */ + trust.private.uni_name_len = strnlen(dom_name, 32); + push_ucs2_talloc(mem_ctx, &uni_name, dom_name); + strncpy_w(trust.private.uni_name, uni_name, 32); + + /* flags */ + for (i = 0; i < flag_num; i++) { + if (!StrCaseCmp(flags[i].name, flag)) { + trust.private.flags = flags[i].val; + i = flag_num; /* stop comparing */ + } + } + + /* trusting SID */ + if (!dom_sid) { + /* if sid is not specified in command line, do our best + to establish it */ + + /* find domain PDC */ + if (!get_pdc_ip(dom_name, &srv_ip)) + return -1; + if (is_zero_ip(srv_ip)) + return -1; + if (!name_status_find(dom_name, 0x1b, 0x20, srv_ip, srv_name)) + return -1; + + get_myname(myname); + + /* Connect the domain pdc... */ + nt_status = cli_full_connection(&cli, myname, srv_name, &srv_ip, 139, + "IPC$", "IPC", "", "", "", 0, Undefined, NULL); + if (NT_STATUS_IS_ERR(nt_status)) + return -1; + if (!cli_nt_session_open(cli, PI_LSARPC)) + return -1; + + /* ...and query the domain sid */ + nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, + &connect_hnd); + if (NT_STATUS_IS_ERR(nt_status)) return -1; + + nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd, + 5, &domain_name, &domain_sid); + if (NT_STATUS_IS_ERR(nt_status)) return -1; + + nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd); + if (NT_STATUS_IS_ERR(nt_status)) return -1; + + cli_nt_session_close(cli); + cli_shutdown(cli); + + /* copying sid to trust password structure */ + sid_copy(&trust.private.domain_sid, domain_sid); + + } else { + if (!string_to_sid(&trust.private.domain_sid, dom_sid)) { + printf("Error: wrong SID specified !\n"); + return -1; + } + } + + /* password */ + givenpass = getpass("password:"); + memset(trust.private.pass, '\0', FSTRING_LEN); + strncpy(trust.private.pass, givenpass, FSTRING_LEN); + + /* last change time */ + lct = time(NULL); + trust.private.mod_time = lct; + + /* store trust password in passdb */ + nt_status = in->pdb_add_trust_passwd(in, &trust); + + talloc_destroy(mem_ctx); + if (NT_STATUS_IS_OK(nt_status)) + return 0; + + return -1; +} + + /********************************************************* Delete user entry **********************************************************/ @@ -603,6 +744,7 @@ int main (int argc, char **argv) static BOOL verbose = False; static BOOL spstyle = False; static BOOL machine = False; + static BOOL trustdom = False; static BOOL add_user = False; static BOOL delete_user = False; static BOOL modify_user = False; @@ -626,6 +768,10 @@ int main (int argc, char **argv) static long int account_policy_value = 0; BOOL account_policy_value_set = False; static BOOL badpw_reset = False; + /* trust password parameters */ + static char *trustpw = NULL; + static char *trustsid = NULL; + static char *trustflags = NULL; struct pdb_context *bin; struct pdb_context *bout; @@ -646,8 +792,12 @@ int main (int argc, char **argv) {"group SID", 'G', POPT_ARG_STRING, &group_sid, 0, "set group SID or RID", NULL}, {"create", 'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL}, {"modify", 'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL}, - {"machine", 'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL}, {"delete", 'x', POPT_ARG_NONE, &delete_user, 0, "delete user", NULL}, + {"machine", 'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL}, + {"trustdom", 'I', POPT_ARG_NONE, &trustdom, 0, "account is a domain trust account", NULL}, + {"trustpw", 'N', POPT_ARG_STRING, &trustpw, 0, "trust password's domain name", NULL}, + {"trustsid", 'T', POPT_ARG_STRING, &trustsid, 0, "trust password's domain sid", NULL}, + {"trustflags", 'F', POPT_ARG_STRING, &trustflags, 0, "trust password flags", NULL}, {"backend", 'b', POPT_ARG_STRING, &backend, 0, "use different passdb backend as default backend", NULL}, {"import", 'i', POPT_ARG_STRING, &backend_in, 0, "import user accounts from this backend", NULL}, {"export", 'e', POPT_ARG_STRING, &backend_out, 0, "export user accounts to this backend", NULL}, @@ -699,6 +849,10 @@ int main (int argc, char **argv) (logon_script ? BIT_LOGSCRIPT : 0) + (profile_path ? BIT_PROFILE : 0) + (machine ? BIT_MACHINE : 0) + + (trustdom ? BIT_TRUSTDOM : 0) + + (trustpw ? BIT_TRUSTPW : 0) + + (trustsid ? BIT_TRUSTSID : 0) + + (trustflags ? BIT_TRUSTFLAGS : 0) + (user_name ? BIT_USER : 0) + (list_users ? BIT_LIST : 0) + (force_initialised_password ? BIT_FIX_INIT : 0) + @@ -817,15 +971,21 @@ int main (int argc, char **argv) /* account operation */ if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) { /* check use of -u option */ - if (!(checkparms & BIT_USER)) { + if (!(checkparms & (BIT_USER + BIT_TRUSTPW))) { fprintf (stderr, "Username not specified! (use -u option)\n"); return -1; } /* account creation operations */ - if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) { + if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE + BIT_TRUSTDOM))) { + /* machine trust account */ if (checkparms & BIT_MACHINE) { return new_machine (bdef, user_name); + /* interdomain trust account */ + } else if (checkparms & BIT_TRUSTDOM) { + return new_trustdom(bdef, user_name); + + /* ordinary user account */ } else { return new_user (bdef, user_name, full_name, home_dir, home_drive, logon_script, @@ -854,6 +1014,15 @@ int main (int argc, char **argv) } } + /* trust password operation */ + if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) { + /* trust password creation */ + if (!(checkparms & ~(BIT_CREATE + BIT_TRUSTPW + BIT_TRUSTSID + BIT_TRUSTFLAGS))) { + return new_trustpw(bdef, trustpw, trustsid, trustflags); + } + } + + if (setparms >= 0x20) { fprintf (stderr, "Incompatible or insufficient options on command line!\n"); } @@ -861,3 +1030,4 @@ int main (int argc, char **argv) return 1; } + -- cgit From 499fec31b624a87dd40d6204afbdcd4c362d1575 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Fri, 27 Feb 2004 22:11:31 +0000 Subject: Added copyrights I forgot about looong ago... rafal (This used to be commit ed26b550b5f24741db6be38542f341be18741e62) --- source3/tdb/tdbutil.c | 3 ++- source3/tdb/tdbutil.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c index 304bf9c816..09e55e2e70 100644 --- a/source3/tdb/tdbutil.c +++ b/source3/tdb/tdbutil.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. tdb utility functions - Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Rafal Szczesniak 2002 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 diff --git a/source3/tdb/tdbutil.h b/source3/tdb/tdbutil.h index 01473446a1..1a181a962f 100644 --- a/source3/tdb/tdbutil.h +++ b/source3/tdb/tdbutil.h @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. tdb utility functions - Copyright (C) Andrew Tridgell 1999 + Copyright (C) Andrew Tridgell 1999 + Copyright (C) Rafal Szczesniak 2002 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 -- cgit From cff0114f2b5965cfc49f39061305ff23fa4f3931 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 28 Feb 2004 00:56:39 +0000 Subject: More gentest fixes. Fix up regression in IS_NAME_VALID and renames. Jeremy. (This used to be commit 2a457e2e28cd1f78778cb41fbb381883ced99592) --- source3/smbd/reply.c | 41 ++++++++++++++++++++++++++++++----------- source3/smbd/trans2.c | 6 ++++-- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 643b7c2d08..836f95e179 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3357,16 +3357,20 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char * pstring newname_last_component; NTSTATUS error = NT_STATUS_OK; BOOL dest_exists; + BOOL rcdest = True; ZERO_STRUCT(sbuf); - unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf); + rcdest = unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf); /* Quick check for "." and ".." */ - if (newname_last_component[0] == '.') { + if (!bad_path && newname_last_component[0] == '.') { if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { return NT_STATUS_ACCESS_DENIED; } } + if (!rcdest && bad_path) { + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } /* Ensure newname contains a '/' */ if(strrchr_m(newname,'/') == 0) { @@ -3472,6 +3476,7 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BO int count=0; NTSTATUS error = NT_STATUS_OK; BOOL rc = True; + BOOL rcdest = True; SMB_STRUCT_STAT sbuf1, sbuf2; *directory = *mask = 0; @@ -3479,15 +3484,7 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BO ZERO_STRUCT(sbuf1); ZERO_STRUCT(sbuf2); rc = unix_convert(name,conn,0,&bad_path1,&sbuf1); - unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2); - - /* Quick check for "." and ".." */ - if (!bad_path2 && newname_last_component[0] == '.') { - if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { - DEBUG(10,("rename_internals: newname_last_component = '.' or '..'\n")); - return NT_STATUS_ACCESS_DENIED; - } - } + rcdest = unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2); /* * Split the old name into directory and last component @@ -3612,6 +3609,17 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", return error; } + /* Quick check for "." and ".." */ + if (!bad_path2 && newname_last_component[0] == '.') { + if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { + DEBUG(10,("rename_internals: newname_last_component = '.' or '..'\n")); + return NT_STATUS_ACCESS_DENIED; + } + } + if (!rcdest && bad_path2) { + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + error = can_rename(directory,conn,&sbuf1); if (!NT_STATUS_IS_OK(error)) { @@ -3661,6 +3669,17 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", const char *dname; pstring destname; + /* Quick check for "." and ".." */ + if (!bad_path2 && newname_last_component[0] == '.') { + if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { + DEBUG(10,("rename_internals: newname_last_component = '.' or '..'\n")); + return NT_STATUS_ACCESS_DENIED; + } + } + if (!rcdest && bad_path2) { + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + if (check_name(directory,conn)) dirptr = OpenDir(conn, directory, True); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 63130aa8d8..5fbc5ce6ee 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1830,6 +1830,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, SMB_OFF_T file_size=0; SMB_BIG_UINT allocation_size=0; unsigned int data_size; + unsigned int param_size = 2; SMB_STRUCT_STAT sbuf; pstring fname, dos_fname; char *fullpathname; @@ -1932,7 +1933,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno))); return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); } - } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) { + } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) { DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno))); return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); } @@ -2016,6 +2017,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, return ERROR_DOS(ERRDOS,ERRbadfunc); } data_size = 0; + param_size = 0; break; case SMB_INFO_QUERY_EAS_FROM_LIST: @@ -2322,7 +2324,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, return ERROR_DOS(ERRDOS,ERRunknownlevel); } - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size); + send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size); return(-1); } -- cgit From a51129c4740cc4795440c193a99cedf844531462 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 28 Feb 2004 01:53:19 +0000 Subject: Can't set allocation size on directories, return correct error code on fail if file exists and target is a directory. gentest. Jeremy. (This used to be commit 4b1262322995c8794cd73d84712f82d8c91abdc6) --- source3/libsmb/errormap.c | 1 + source3/smbd/nttrans.c | 12 ++++++++++++ source3/smbd/open.c | 6 +++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 116d2cefe1..aeb68b6596 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1503,6 +1503,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, { ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY }, + { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, #ifdef EDQUOT { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, #endif diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index a8a314c876..1afcf0af63 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -896,6 +896,12 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib #endif if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) { fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE); + if (fsp->is_directory) { + close_file(fsp,False); + END_PROFILE(SMBntcreateX); + /* Can't set allocation size on a directory. */ + return ERROR_NT(NT_STATUS_ACCESS_DENIED); + } if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { close_file(fsp,False); END_PROFILE(SMBntcreateX); @@ -1405,6 +1411,12 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o #endif if (allocation_size && (allocation_size > file_len)) { fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE); + if (fsp->is_directory) { + close_file(fsp,False); + END_PROFILE(SMBntcreateX); + /* Can't set allocation size on a directory. */ + return ERROR_NT(NT_STATUS_ACCESS_DENIED); + } if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { close_file(fsp,False); return ERROR_NT(NT_STATUS_DISK_FULL); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index dd10a87055..e688f8de48 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -866,7 +866,11 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_ DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n", fname )); file_free(fsp); - errno = EEXIST; + if (S_ISDIR(psbuf->st_mode)) { + errno = EISDIR; + } else { + errno = EEXIST; + } return NULL; } -- cgit From 6cf54c5fbea99109d45beb50098fbe3c0eb0b6ce Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 28 Feb 2004 08:19:00 +0000 Subject: Fix my fix to net rpc group list. We can certainly have more than a single set of groups. Volker (This used to be commit 710969acaa9ce4467ec09c2fadb03e49fbc207be) --- source3/utils/net_rpc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index e46dfe7fd4..a3c4e7a135 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1193,7 +1193,8 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name, &start_idx, 3, &num_entries, max_entries, max_size, &ctr); - if (!NT_STATUS_IS_OK(result)) + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break; for (i = 0; i < num_entries; i++) { @@ -1219,7 +1220,8 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name, &start_idx, max_entries, &groups, &num_entries); - if (!NT_STATUS_IS_OK(result)) + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break; for (i = 0; i < num_entries; i++) { @@ -1273,7 +1275,8 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name, &start_idx, max_entries, &groups, &num_entries); - if (!NT_STATUS_IS_OK(result)) + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break; for (i = 0; i < num_entries; i++) { -- cgit From 3e2e8d2f4d7fea7be34a10dbf4796a8b8edcf8c6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 28 Feb 2004 18:42:20 +0000 Subject: Add 'net rpc group [add|del]mem' for domain groups and aliases. Volker (This used to be commit 6785dc84ce4d9c2d5ebe3113c7f506947b09a7f8) --- source3/rpc_client/cli_pipe.c | 2 + source3/rpc_client/cli_samr.c | 275 +++++++++++++++++++++++++ source3/rpc_parse/parse_samr.c | 6 +- source3/utils/net_rpc.c | 452 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 732 insertions(+), 3 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3213e955b6..b9511ae00f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1466,6 +1466,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) return False; } + cli->pipe_idx = pipe_idx; + /* * Setup the remote server name prefixed by \ and the machine account name. */ diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index c924e33f8a..d534745d25 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -371,6 +371,94 @@ NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Add a domain group member */ + +NTSTATUS cli_samr_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 rid) +{ + prs_struct qbuf, rbuf; + SAMR_Q_ADD_GROUPMEM q; + SAMR_R_ADD_GROUPMEM r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + DEBUG(10,("cli_samr_add_groupmem\n")); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_add_groupmem(&q, group_pol, rid); + + if (!samr_io_q_add_groupmem("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_ADD_GROUPMEM, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!samr_io_r_add_groupmem("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Delete a domain group member */ + +NTSTATUS cli_samr_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 rid) +{ + prs_struct qbuf, rbuf; + SAMR_Q_DEL_GROUPMEM q; + SAMR_R_DEL_GROUPMEM r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + DEBUG(10,("cli_samr_del_groupmem\n")); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_del_groupmem(&q, group_pol, rid); + + if (!samr_io_q_del_groupmem("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_DEL_GROUPMEM, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!samr_io_r_del_groupmem("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Query user info */ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, @@ -556,6 +644,50 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Set alias info */ + +NTSTATUS cli_samr_set_aliasinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_SET_ALIASINFO q; + SAMR_R_SET_ALIASINFO r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + DEBUG(10,("cli_samr_set_aliasinfo\n")); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_set_aliasinfo(&q, alias_pol, ctr); + + if (!samr_io_q_set_aliasinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_SET_ALIASINFO, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!samr_io_r_set_aliasinfo("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Query user aliases */ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, @@ -1034,6 +1166,149 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Create an alias */ + +NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, const char *name, + POLICY_HND *alias_pol) +{ + prs_struct qbuf, rbuf; + SAMR_Q_CREATE_DOM_ALIAS q; + SAMR_R_CREATE_DOM_ALIAS r; + NTSTATUS result; + + DEBUG(10,("cli_samr_create_dom_alias named %s\n", name)); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_create_dom_alias(&q, domain_pol, name); + + if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_create_dom_alias("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if (NT_STATUS_IS_OK(result = r.status)) { + *alias_pol = r.alias_pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Add an alias member */ + +NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *alias_pol, DOM_SID *member) +{ + prs_struct qbuf, rbuf; + SAMR_Q_ADD_ALIASMEM q; + SAMR_R_ADD_ALIASMEM r; + NTSTATUS result; + + DEBUG(10,("cli_samr_add_aliasmem")); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_add_aliasmem(&q, alias_pol, member); + + if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_add_aliasmem("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Delete an alias member */ + +NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *alias_pol, DOM_SID *member) +{ + prs_struct qbuf, rbuf; + SAMR_Q_DEL_ALIASMEM q; + SAMR_R_DEL_ALIASMEM r; + NTSTATUS result; + + DEBUG(10,("cli_samr_del_aliasmem")); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_del_aliasmem(&q, alias_pol, member); + + if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_del_aliasmem("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Query alias info */ NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 402f23bde8..287dc3bd7f 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -3521,7 +3521,7 @@ BOOL samr_io_alias_info1(const char *desc, ALIAS_INFO1 * al1, inits a ALIAS_INFO3 structure. ********************************************************************/ -void init_samr_alias_info3(ALIAS_INFO3 * al3, char *acct_desc) +void init_samr_alias_info3(ALIAS_INFO3 * al3, const char *acct_desc) { DEBUG(5, ("init_samr_alias_info3\n")); @@ -4232,7 +4232,7 @@ inits a SAMR_Q_CREATE_DOM_ALIAS structure. ********************************************************************/ void init_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS * q_u, - POLICY_HND *hnd, char *acct_desc) + POLICY_HND *hnd, const char *acct_desc) { DEBUG(5, ("init_samr_q_create_dom_alias\n")); @@ -4241,7 +4241,7 @@ void init_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS * q_u, init_unistr2(&q_u->uni_acct_desc, acct_desc, UNI_FLAGS_NONE); init_uni_hdr(&q_u->hdr_acct_desc, &q_u->uni_acct_desc); - q_u->access_mask = 0x001f000f; + q_u->access_mask = MAXIMUM_ALLOWED_ACCESS; } /******************************************************************* diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index a3c4e7a135..2e30a47afa 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1098,13 +1098,463 @@ rpc_group_add_internals(const DOM_SID *domain_sid, const char *domain_name, return result; } +static NTSTATUS +rpc_alias_add_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + POLICY_HND connect_pol, domain_pol, alias_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + ALIAS_INFO_CTR alias_info; + + if (argc != 1) { + d_printf("Group name must be specified\n"); + rpc_group_usage(argc, argv); + return NT_STATUS_OK; + } + + /* Get sam policy handle */ + + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) goto done; + + /* Get domain policy handle */ + + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + domain_sid, &domain_pol); + if (!NT_STATUS_IS_OK(result)) goto done; + + /* Create the group */ + + result = cli_samr_create_dom_alias(cli, mem_ctx, &domain_pol, + argv[0], &alias_pol); + if (!NT_STATUS_IS_OK(result)) goto done; + + if (strlen(opt_comment) == 0) goto done; + + /* We've got a comment to set */ + + alias_info.switch_value1 = 3; + alias_info.switch_value2 = 3; + init_samr_alias_info3(&alias_info.alias.info3, opt_comment); + + result = cli_samr_set_aliasinfo(cli, mem_ctx, &alias_pol, &alias_info); + if (!NT_STATUS_IS_OK(result)) goto done; + + done: + if (NT_STATUS_IS_OK(result)) + DEBUG(5, ("add group succeeded\n")); + else + d_printf("add group failed: %s\n", nt_errstr(result)); + + return result; +} + static int rpc_group_add(int argc, const char **argv) { + if (opt_localgroup) + return run_rpc_command(NULL, PI_SAMR, 0, + rpc_alias_add_internals, + argc, argv); + return run_rpc_command(NULL, PI_SAMR, 0, rpc_group_add_internals, argc, argv); } +static NTSTATUS +get_sid_from_name(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *name, + DOM_SID *sid, enum SID_NAME_USE *type) +{ + int current_pipe = cli->pipe_idx; + + DOM_SID *sids = NULL; + uint32 *types = NULL; + POLICY_HND lsa_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + if (current_pipe != PI_LSARPC) { + + if (current_pipe != -1) + cli_nt_session_close(cli); + + if (!cli_nt_session_open(cli, PI_LSARPC)) + goto done; + } + + result = cli_lsa_open_policy(cli, mem_ctx, False, + SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = cli_lsa_lookup_names(cli, mem_ctx, &lsa_pol, 1, + &name, &sids, &types); + + if (NT_STATUS_IS_OK(result)) { + sid_copy(sid, &sids[0]); + *type = types[0]; + } + + cli_lsa_close(cli, mem_ctx, &lsa_pol); + + done: + if (current_pipe != PI_LSARPC) { + cli_nt_session_close(cli); + if (current_pipe != -1) + cli_nt_session_open(cli, current_pipe); + } + + if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) { + + /* Try as S-1-5-whatever */ + + DOM_SID tmp_sid; + + if (string_to_sid(&tmp_sid, name)) { + sid_copy(sid, &tmp_sid); + *type = SID_NAME_UNKNOWN; + result = NT_STATUS_OK; + } + } + + return result; +} + +static NTSTATUS +rpc_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const DOM_SID *group_sid, const char *member) +{ + POLICY_HND connect_pol, domain_pol; + NTSTATUS result; + uint32 group_rid; + POLICY_HND group_pol; + + uint32 num_rids; + uint32 *rids = NULL; + uint32 *rid_types = NULL; + + DOM_SID sid; + + sid_copy(&sid, group_sid); + + if (!sid_split_rid(&sid, &group_rid)) + return NT_STATUS_UNSUCCESSFUL; + + /* Get sam policy handle */ + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) + return result; + + /* Get domain policy handle */ + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &sid, &domain_pol); + if (!NT_STATUS_IS_OK(result)) + return result; + + result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, + 1, &member, + &num_rids, &rids, &rid_types); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Could not lookup up group member %s\n", member); + goto done; + } + + result = cli_samr_open_group(cli, mem_ctx, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + group_rid, &group_pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = cli_samr_add_groupmem(cli, mem_ctx, &group_pol, rids[0]); + + done: + cli_samr_close(cli, mem_ctx, &connect_pol); + return result; +} + +static NTSTATUS +rpc_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const DOM_SID *alias_sid, const char *member) +{ + POLICY_HND connect_pol, domain_pol; + NTSTATUS result; + uint32 alias_rid; + POLICY_HND alias_pol; + + DOM_SID member_sid; + enum SID_NAME_USE member_type; + + DOM_SID sid; + + sid_copy(&sid, alias_sid); + + if (!sid_split_rid(&sid, &alias_rid)) + return NT_STATUS_UNSUCCESSFUL; + + result = get_sid_from_name(cli, mem_ctx, member, + &member_sid, &member_type); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Could not lookup up group member %s\n", member); + return result; + } + + /* Get sam policy handle */ + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Get domain policy handle */ + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &sid, &domain_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = cli_samr_open_alias(cli, mem_ctx, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + alias_rid, &alias_pol); + + if (!NT_STATUS_IS_OK(result)) + return result; + + result = cli_samr_add_aliasmem(cli, mem_ctx, &alias_pol, &member_sid); + + if (!NT_STATUS_IS_OK(result)) + return result; + + done: + cli_samr_close(cli, mem_ctx, &connect_pol); + return result; +} + +static NTSTATUS +rpc_group_addmem_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + DOM_SID group_sid; + enum SID_NAME_USE group_type; + + if (argc != 2) { + d_printf("Usage: 'net rpc group addmem \n"); + return NT_STATUS_UNSUCCESSFUL; + } + + if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0], + &group_sid, &group_type))) { + d_printf("Could not lookup group name %s\n", argv[0]); + return NT_STATUS_UNSUCCESSFUL; + } + + if (group_type == SID_NAME_DOM_GRP) { + NTSTATUS result = rpc_add_groupmem(cli, mem_ctx, + &group_sid, argv[1]); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Could not add %s to %s: %s\n", + argv[1], argv[0], nt_errstr(result)); + return result; + } + } + + if (group_type == SID_NAME_ALIAS) { + NTSTATUS result = rpc_add_aliasmem(cli, mem_ctx, + &group_sid, argv[1]); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Could not add %s to %s: %s\n", + argv[1], argv[0], nt_errstr(result)); + return result; + } + } + + return NT_STATUS_UNSUCCESSFUL; +} + +static int rpc_group_addmem(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_SAMR, 0, + rpc_group_addmem_internals, + argc, argv); +} + +static NTSTATUS +rpc_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const DOM_SID *group_sid, const char *member) +{ + POLICY_HND connect_pol, domain_pol; + NTSTATUS result; + uint32 group_rid; + POLICY_HND group_pol; + + uint32 num_rids; + uint32 *rids = NULL; + uint32 *rid_types = NULL; + + DOM_SID sid; + + sid_copy(&sid, group_sid); + + if (!sid_split_rid(&sid, &group_rid)) + return NT_STATUS_UNSUCCESSFUL; + + /* Get sam policy handle */ + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) + return result; + + /* Get domain policy handle */ + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &sid, &domain_pol); + if (!NT_STATUS_IS_OK(result)) + return result; + + result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, + 1, &member, + &num_rids, &rids, &rid_types); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Could not lookup up group member %s\n", member); + goto done; + } + + result = cli_samr_open_group(cli, mem_ctx, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + group_rid, &group_pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + result = cli_samr_del_groupmem(cli, mem_ctx, &group_pol, rids[0]); + + done: + cli_samr_close(cli, mem_ctx, &connect_pol); + return result; +} + +static NTSTATUS +rpc_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const DOM_SID *alias_sid, const char *member) +{ + POLICY_HND connect_pol, domain_pol; + NTSTATUS result; + uint32 alias_rid; + POLICY_HND alias_pol; + + DOM_SID member_sid; + enum SID_NAME_USE member_type; + + DOM_SID sid; + + sid_copy(&sid, alias_sid); + + if (!sid_split_rid(&sid, &alias_rid)) + return NT_STATUS_UNSUCCESSFUL; + + result = get_sid_from_name(cli, mem_ctx, member, + &member_sid, &member_type); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Could not lookup up group member %s\n", member); + return result; + } + + /* Get sam policy handle */ + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Get domain policy handle */ + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &sid, &domain_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = cli_samr_open_alias(cli, mem_ctx, &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + alias_rid, &alias_pol); + + if (!NT_STATUS_IS_OK(result)) + return result; + + result = cli_samr_del_aliasmem(cli, mem_ctx, &alias_pol, &member_sid); + + if (!NT_STATUS_IS_OK(result)) + return result; + + done: + cli_samr_close(cli, mem_ctx, &connect_pol); + return result; +} + +static NTSTATUS +rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + DOM_SID group_sid; + enum SID_NAME_USE group_type; + + if (argc != 2) { + d_printf("Usage: 'net rpc group delmem \n"); + return NT_STATUS_UNSUCCESSFUL; + } + + if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0], + &group_sid, &group_type))) { + d_printf("Could not lookup group name %s\n", argv[0]); + return NT_STATUS_UNSUCCESSFUL; + } + + if (group_type == SID_NAME_DOM_GRP) { + NTSTATUS result = rpc_del_groupmem(cli, mem_ctx, + &group_sid, argv[1]); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Could not del %s to %s: %s\n", + argv[1], argv[0], nt_errstr(result)); + return result; + } + } + + if (group_type == SID_NAME_ALIAS) { + NTSTATUS result = rpc_del_aliasmem(cli, mem_ctx, + &group_sid, argv[1]); + + if (!NT_STATUS_IS_OK(result)) { + d_printf("Could not add %s to %s: %s\n", + argv[1], argv[0], nt_errstr(result)); + return result; + } + } + + return NT_STATUS_UNSUCCESSFUL; +} + +static int rpc_group_delmem(int argc, const char **argv) +{ + return run_rpc_command(NULL, PI_SAMR, 0, + rpc_group_delmem_internals, + argc, argv); +} + /** * List groups on a remote RPC server * @@ -1563,6 +2013,8 @@ int net_rpc_group(int argc, const char **argv) { struct functable func[] = { {"add", rpc_group_add}, + {"addmem", rpc_group_addmem}, + {"delmem", rpc_group_delmem}, #if 0 {"delete", rpc_group_delete}, #endif -- cgit From 55afdfa77cd2efce116bf27fd98aff9f73feb283 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 29 Feb 2004 12:48:29 +0000 Subject: Print an informative error message if trying to add/remove members from something not a group. Volker (This used to be commit 9cfc97df456199c22e199831d28597132cf001a8) --- source3/utils/net_rpc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 2e30a47afa..a565effeff 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1379,6 +1379,9 @@ rpc_group_addmem_internals(const DOM_SID *domain_sid, const char *domain_name, } } + d_printf("Can only add members to global or local groups which " + "%s is not\n", argv[0]); + return NT_STATUS_UNSUCCESSFUL; } @@ -1545,6 +1548,9 @@ rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name, } } + d_printf("Can only delete members from global or local groups which " + "%s is not\n", argv[0]); + return NT_STATUS_UNSUCCESSFUL; } -- cgit From 6ed848877e4cfbefcbcc1a50f23a906e7afeb55f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 29 Feb 2004 16:32:04 +0000 Subject: Trivial commit to make 'smbdiff 3_0/source head/source' two files smaller. Volker (This used to be commit 73117f5e41aa923b07d200a18c84b8082d8b71a6) --- source3/utils/smbpasswd.c | 1 + source3/web/swat.c | 1 + 2 files changed, 2 insertions(+) diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 5507727498..0476a2e39c 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -37,6 +37,7 @@ static const char *remote_machine = NULL; static fstring ldap_secret; + /********************************************************* Print command usage on stderr and die. **********************************************************/ diff --git a/source3/web/swat.c b/source3/web/swat.c index c536e12e09..e535106f26 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -51,6 +51,7 @@ static int iNumNonAutoPrintServices = 0; #define ENABLE_USER_FLAG "enable_user_flag" #define RHOST "remote_host" + /**************************************************************************** ****************************************************************************/ static int enum_index(int value, const struct enum_list *enumlist) -- cgit From 4628a2da1e32f397696640452c950e4b55ada9e7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 29 Feb 2004 16:33:49 +0000 Subject: net_rpc.c: Don't complain if [add|del]mem was successful. srv_samr_nt.c: Correctly report that a user is not member of an alias. Volker (This used to be commit 26d99204b7cbfa8e259f2a8438eadc9ff6be0709) --- source3/rpc_server/srv_samr_nt.c | 2 +- source3/utils/net_rpc.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 58dcd48d8d..a817627127 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3477,7 +3477,7 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE /* if the user is not in the group */ if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) { pdb_free_sam(&sam_pass); - return NT_STATUS_MEMBER_IN_ALIAS; + return NT_STATUS_MEMBER_NOT_IN_ALIAS; } smb_delete_user_group(grp_name, pdb_get_username(sam_pass)); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index a565effeff..19825ff51b 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1364,8 +1364,8 @@ rpc_group_addmem_internals(const DOM_SID *domain_sid, const char *domain_name, if (!NT_STATUS_IS_OK(result)) { d_printf("Could not add %s to %s: %s\n", argv[1], argv[0], nt_errstr(result)); - return result; } + return result; } if (group_type == SID_NAME_ALIAS) { @@ -1375,8 +1375,8 @@ rpc_group_addmem_internals(const DOM_SID *domain_sid, const char *domain_name, if (!NT_STATUS_IS_OK(result)) { d_printf("Could not add %s to %s: %s\n", argv[1], argv[0], nt_errstr(result)); - return result; } + return result; } d_printf("Can only add members to global or local groups which " @@ -1533,8 +1533,8 @@ rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name, if (!NT_STATUS_IS_OK(result)) { d_printf("Could not del %s to %s: %s\n", argv[1], argv[0], nt_errstr(result)); - return result; } + return result; } if (group_type == SID_NAME_ALIAS) { @@ -1544,8 +1544,8 @@ rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name, if (!NT_STATUS_IS_OK(result)) { d_printf("Could not add %s to %s: %s\n", argv[1], argv[0], nt_errstr(result)); - return result; } + return result; } d_printf("Can only delete members from global or local groups which " -- cgit From 0d45ad1b0d55546c6a4afcb002acefefc2e2feb0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 29 Feb 2004 16:48:19 +0000 Subject: Apply my experimental aliases support to HEAD. This will be a bit difficult to merge to 3_0, as the pdb interfaces has changed a bit between the two. This has not been tested too severly (which means it's completely broken ;-), but I want it in for review. Feel free to revert it :-) TODO: make 'net groupmap' a bit more friendly for alias members. Put that stuff into pdb_ldap. Getting the information over to winbind. One plan without linking pdb into winbind would be to fill group_mapping.tdb with the membership information and have that as a cache (or use gencache.tdb?). smbd on a PDC or stand-alone could trigger that itself, the problem is a BDC using LDAP. This needs to do it on a regular basis. The BDC smbd needs to be informed about SAM changes somehow... Volker (This used to be commit 30ef8fe1e85c0ca229b54f3f1595c4330f7191d1) --- source3/auth/auth_util.c | 66 +++++++++ source3/groupdb/mapping.c | 282 ++++++++++++++++++++++++++++++++++++++- source3/include/passdb.h | 28 ++++ source3/passdb/pdb_interface.c | 121 +++++++++++++++++ source3/rpc_server/srv_samr_nt.c | 9 +- source3/utils/net_groupmap.c | 112 ++++++++++++++++ 6 files changed, 614 insertions(+), 4 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 0f945b33cb..912432b98f 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -635,6 +635,70 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, return token; } +static void add_gid_to_array_unique(gid_t gid, gid_t **groups, int *ngroups) +{ + int i; + + if ((*ngroups) >= groups_max()) + return; + + for (i=0; i<*ngroups; i++) { + if ((*groups)[i] == gid) + return; + } + + *groups = Realloc(*groups, ((*ngroups)+1) * sizeof(gid_t)); + + if (*groups == NULL) + return; + + (*groups)[*ngroups] = gid; + *ngroups += 1; +} + +static void add_foreign_gids_from_sid(const DOM_SID *sid, gid_t **groups, + int *ngroups) +{ + DOM_SID *aliases; + int j, num_aliases; + + if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) + return; + + for (j=0; jsid_name_use != SID_NAME_ALIAS) + if ( ( (map->sid_name_use != SID_NAME_ALIAS) && + (map->sid_name_use != SID_NAME_WKN_GRP) ) || (map->gid == -1) || (getgrgid(map->gid) == NULL) ) { @@ -704,6 +946,9 @@ BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids) int i=0; char *gr; DOM_SID *s; + DOM_SID sid; + DOM_SID *members; + int num_members; struct sys_pwent *userlist; struct sys_pwent *user; @@ -803,6 +1048,15 @@ BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids) DEBUG(10, ("got primary groups, members: [%d]\n", *num_sids)); winbind_on(); + + if ( NT_STATUS_IS_OK(gid_to_sid(&sid, gid)) && + NT_STATUS_IS_OK(enum_aliasmem(&sid, &members, &num_members)) ) { + + for (i=0; ipdb_methods)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods->add_aliasmem(context->pdb_methods, + alias, member); +} + +static NTSTATUS context_del_aliasmem(struct pdb_context *context, + const DOM_SID *alias, + const DOM_SID *member) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + if ((!context) || (!context->pdb_methods)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods->del_aliasmem(context->pdb_methods, + alias, member); +} + +static NTSTATUS context_enum_aliasmem(struct pdb_context *context, + const DOM_SID *alias, DOM_SID **members, + int *num) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + if ((!context) || (!context->pdb_methods)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods->enum_aliasmem(context->pdb_methods, + alias, members, num); +} + +static NTSTATUS context_enum_alias_memberships(struct pdb_context *context, + const DOM_SID *sid, + DOM_SID **aliases, int *num) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + if ((!context) || (!context->pdb_methods)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods-> + enum_alias_memberships(context->pdb_methods, sid, aliases, + num); +} + static NTSTATUS context_gettrustpwent(struct pdb_context *context, SAM_TRUST_PASSWD *trust) { @@ -641,6 +702,10 @@ static NTSTATUS make_pdb_context(struct pdb_context **context) (*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry; (*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry; (*context)->pdb_enum_group_mapping = context_enum_group_mapping; + (*context)->pdb_add_aliasmem = context_add_aliasmem; + (*context)->pdb_del_aliasmem = context_del_aliasmem; + (*context)->pdb_enum_aliasmem = context_enum_aliasmem; + (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships; (*context)->pdb_gettrustpwent = context_gettrustpwent; (*context)->pdb_gettrustpwsid = context_gettrustpwsid; (*context)->pdb_add_trust_passwd = context_add_trust_passwd; @@ -955,6 +1020,58 @@ BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, rmap, num_entries, unix_only)); } +BOOL pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context-> + pdb_add_aliasmem(pdb_context, alias, member)); +} + +BOOL pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context-> + pdb_add_aliasmem(pdb_context, alias, member)); +} + +BOOL pdb_enum_aliasmem(const DOM_SID *alias, + DOM_SID **members, int *num_members) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context-> + pdb_enum_aliasmem(pdb_context, alias, + members, num_members)); +} + +BOOL pdb_enum_alias_memberships(const DOM_SID *sid, + DOM_SID **aliases, int *num) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context-> + pdb_enum_alias_memberships(pdb_context, sid, + aliases, num)); +} + /*************************************************************** Initialize the static context (at smbd startup etc). @@ -1065,6 +1182,10 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry; (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry; (*methods)->enum_group_mapping = pdb_default_enum_group_mapping; + (*methods)->add_aliasmem = pdb_default_add_aliasmem; + (*methods)->del_aliasmem = pdb_default_del_aliasmem; + (*methods)->enum_aliasmem = pdb_default_enum_aliasmem; + (*methods)->enum_alias_memberships = pdb_default_alias_memberships; (*methods)->gettrustpwent = pdb_default_gettrustpwent; (*methods)->gettrustpwsid = pdb_default_gettrustpwsid; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index a817627127..b50d44d9e3 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3381,7 +3381,8 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD if (check != True) { pdb_free_sam(&sam_user); - return NT_STATUS_NO_SUCH_USER; + return pdb_add_aliasmem(&alias_sid, &q_u->sid.sid) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } /* check a real user exist before we run the script to add a user to a group */ @@ -3457,7 +3458,8 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE return NT_STATUS_NO_SUCH_ALIAS; } - if( !get_local_group_from_sid(&alias_sid, &map)) + if( !get_local_group_from_sid(&alias_sid, &map) && + !get_builtin_group_from_sid(&alias_sid, &map) ) return NT_STATUS_NO_SUCH_ALIAS; if ((grp=getgrgid(map.gid)) == NULL) @@ -3471,7 +3473,8 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) { DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass))); pdb_free_sam(&sam_pass); - return NT_STATUS_NO_SUCH_USER; + return pdb_del_aliasmem(&alias_sid, &q_u->sid.sid) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } /* if the user is not in the group */ diff --git a/source3/utils/net_groupmap.c b/source3/utils/net_groupmap.c index 2b487ef17b..48406f72b8 100644 --- a/source3/utils/net_groupmap.c +++ b/source3/utils/net_groupmap.c @@ -608,6 +608,104 @@ static int net_groupmap_cleanup(int argc, const char **argv) return 0; } +static int net_groupmap_addmem(int argc, const char **argv) +{ + DOM_SID alias, member; + NTSTATUS result; + + if ( (argc != 2) || + !string_to_sid(&alias, argv[0]) || + !string_to_sid(&member, argv[1]) ) { + d_printf("Usage: net groupmap addmem alias-sid member-sid\n"); + return -1; + } + + if (!pdb_add_aliasmem(&alias, &member)) { + d_printf("Could not add sid %s to alias %s: %s\n", + argv[1], argv[0], nt_errstr(result)); + return -1; + } + + return 0; +} + +static int net_groupmap_delmem(int argc, const char **argv) +{ + DOM_SID alias, member; + NTSTATUS result; + + if ( (argc != 2) || + !string_to_sid(&alias, argv[0]) || + !string_to_sid(&member, argv[1]) ) { + d_printf("Usage: net groupmap delmem alias-sid member-sid\n"); + return -1; + } + + if (!pdb_del_aliasmem(&alias, &member)) { + d_printf("Could not delete sid %s from alias %s: %s\n", + argv[1], argv[0], nt_errstr(result)); + return -1; + } + + return 0; +} + +static int net_groupmap_listmem(int argc, const char **argv) +{ + DOM_SID alias; + DOM_SID *members; + int i, num; + NTSTATUS result; + + if ( (argc != 1) || + !string_to_sid(&alias, argv[0]) ) { + d_printf("Usage: net groupmap listmem alias-sid\n"); + return -1; + } + + if (!pdb_enum_aliasmem(&alias, &members, &num)) { + d_printf("Could not list members for sid %s: %s\n", + argv[0], nt_errstr(result)); + return -1; + } + + for (i = 0; i < num; i++) { + printf("%s\n", sid_string_static(&(members[i]))); + } + + SAFE_FREE(members); + + return 0; +} + +static int net_groupmap_memberships(int argc, const char **argv) +{ + DOM_SID member; + DOM_SID *aliases; + int i, num; + NTSTATUS result; + + if ( (argc != 1) || + !string_to_sid(&member, argv[0]) ) { + d_printf("Usage: net groupmap memberof sid\n"); + return -1; + } + + if (!pdb_enum_alias_memberships(&member, &aliases, &num)) { + d_printf("Could not list memberships for sid %s: %s\n", + argv[0], nt_errstr(result)); + return -1; + } + + for (i = 0; i < num; i++) { + printf("%s\n", sid_string_static(&(aliases[i]))); + } + + SAFE_FREE(aliases); + + return 0; +} + int net_help_groupmap(int argc, const char **argv) { d_printf("net groupmap add"\ @@ -616,6 +714,14 @@ int net_help_groupmap(int argc, const char **argv) "\n Update a group mapping\n"); d_printf("net groupmap delete"\ "\n Remove a group mapping\n"); + d_printf("net groupmap addmember"\ + "\n Add a foreign alias member\n"); + d_printf("net groupmap delmember"\ + "\n Delete a foreign alias member\n"); + d_printf("net groupmap listmembers"\ + "\n List foreign group members\n"); + d_printf("net groupmap memberships"\ + "\n List foreign group memberships\n"); d_printf("net groupmap list"\ "\n List current group map\n"); d_printf("net groupmap set"\ @@ -638,16 +744,22 @@ int net_groupmap(int argc, const char **argv) {"delete", net_groupmap_delete}, {"set", net_groupmap_set}, {"cleanup", net_groupmap_cleanup}, + {"addmem", net_groupmap_addmem}, + {"delmem", net_groupmap_delmem}, + {"listmem", net_groupmap_listmem}, + {"memberships", net_groupmap_memberships}, {"list", net_groupmap_list}, {"help", net_help_groupmap}, {NULL, NULL} }; /* we shouldn't have silly checks like this */ +#if 0 if (getuid() != 0) { d_printf("You must be root to edit group mappings.\nExiting...\n"); return -1; } +#endif if ( argc ) return net_run_function(argc, argv, func, net_help_groupmap); -- cgit From 0af6ee14c1ab480e5a3d2e82f803253581a2896f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 1 Mar 2004 01:09:13 +0000 Subject: Fix bugzilla #1144 where running configure --with-fhs=anything would turn on fhs compliant paths. Spotted by Timur Bakeyev. (This used to be commit e0382635a5490e1a6b6388dc98e6ce318e197808) --- source3/configure.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index fec57ee1f3..9fffe7c3c6 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -16,6 +16,8 @@ AC_PREFIX_DEFAULT(/usr/local/samba) AC_ARG_WITH(fhs, [ --with-fhs Use FHS-compliant paths (default=no)], +[ case "$withval" in + yes) configdir="${sysconfdir}/samba" lockdir="\${VARDIR}/lib/samba" piddir="\${VARDIR}/run" @@ -29,7 +31,9 @@ AC_ARG_WITH(fhs, lockdir="\${VARDIR}/locks" piddir="\${VARDIR}/locks" privatedir="\${prefix}/private" - swatdir="\${prefix}/swat") + swatdir="\${prefix}/swat" + ;; + esac]) ################################################# # set private directory location -- cgit From 480fd4f9b558b668c77af2825963e5f9c616c165 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 1 Mar 2004 13:02:06 +0000 Subject: Add aliases to winbindd_getgroups(). su - WINDOWS\\vl now includes the locally defined aliases I'm member of. Next will be getent group. Volker (This used to be commit 52dae45684317ac8ac529017607bb5787dda7c50) --- source3/auth/auth_util.c | 41 --------------------------- source3/groupdb/mapping.c | 39 +++++++++++++++----------- source3/nsswitch/winbindd_group.c | 58 +++++++++++++++++++-------------------- source3/passdb/util_sam_sid.c | 57 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 86 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 912432b98f..4a23593936 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -635,47 +635,6 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, return token; } -static void add_gid_to_array_unique(gid_t gid, gid_t **groups, int *ngroups) -{ - int i; - - if ((*ngroups) >= groups_max()) - return; - - for (i=0; i<*ngroups; i++) { - if ((*groups)[i] == gid) - return; - } - - *groups = Realloc(*groups, ((*ngroups)+1) * sizeof(gid_t)); - - if (*groups == NULL) - return; - - (*groups)[*ngroups] = gid; - *ngroups += 1; -} - -static void add_foreign_gids_from_sid(const DOM_SID *sid, gid_t **groups, - int *ngroups) -{ - DOM_SID *aliases; - int j, num_aliases; - - if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) - return; - - for (j=0; jnum_groups2, info3->num_other_sids)); num_groups = info3->num_other_sids + info3->num_groups2; - gid_list = calloc(sizeof(gid_t), num_groups); /* Go through each other sid and convert it to a gid */ @@ -1004,23 +1019,11 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) continue; } - /* Map to a gid */ + add_gids_from_sid(&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))); - continue; - } - - /* We've jumped through a lot of hoops to get here */ - - DEBUG(10, ("winbindd_getgroups: mapped other sid %s to " - "gid %lu\n", sid_string_static( - &info3->other_sids[i].sid), - (unsigned long)gid_list[num_gids])); - - num_gids++; + if (gid_list == NULL) + goto done; } for (i = 0; i < info3->num_groups2; i++) { @@ -1030,12 +1033,10 @@ 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(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))); - } + add_gids_from_sid(&group_sid, &gid_list, &num_gids); - num_gids++; + if (gid_list == NULL) + goto done; } SAFE_FREE(info3); @@ -1053,12 +1054,11 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; for (i = 0; i < num_groups; i++) { - 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; - } - num_gids++; + add_gids_from_sid(user_grpsids[i], + &gid_list, &num_gids); + + if (gid_list == NULL) + goto done; } } diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c index f6cc2491a8..db88ea7aea 100644 --- a/source3/passdb/util_sam_sid.c +++ b/source3/passdb/util_sam_sid.c @@ -305,3 +305,60 @@ BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char return False; } + +void add_sid_to_array(DOM_SID sid, DOM_SID **sids, int *num) +{ + *sids = Realloc(*sids, ((*num)+1) * sizeof(DOM_SID)); + + if (*sids == NULL) + return; + + sid_copy(&((*sids)[*num]), &sid); + *num += 1; + + return; +} + +void add_gid_to_array_unique(gid_t gid, gid_t **gids, int *num) +{ + int i; + + if ((*num) >= groups_max()) + return; + + for (i=0; i<*num; i++) { + if ((*gids)[i] == gid) + return; + } + + *gids = Realloc(*gids, (*num+1) * sizeof(gid_t)); + + if (*gids == NULL) + return; + + (*gids)[*num] = gid; + *num += 1; +} + +/************************************************************************** + Augment a gid list with gids from alias memberships +***************************************************************************/ + +void add_foreign_gids_from_sid(const DOM_SID *sid, gid_t **gids, int *num) +{ + DOM_SID *aliases; + int j, num_aliases; + + if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) + return; + + for (j=0; j Date: Mon, 1 Mar 2004 13:07:04 +0000 Subject: When asked to delete an alias member, don't add it ... Volker (This used to be commit f95a5d81479b467c837b727831c2224832c8205c) --- source3/passdb/pdb_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 83aebf654a..2005885c45 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1041,7 +1041,7 @@ BOOL pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member) } return NT_STATUS_IS_OK(pdb_context-> - pdb_add_aliasmem(pdb_context, alias, member)); + pdb_del_aliasmem(pdb_context, alias, member)); } BOOL pdb_enum_aliasmem(const DOM_SID *alias, -- cgit From f986f33aa13f8672e2154f29906f657c023777dc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 1 Mar 2004 14:59:32 +0000 Subject: Fix Tim's fix for #1144. Tim, could you look at that again? With only your fix in for example smb.conf was expected in /smb.conf... Thanks, Volker (This used to be commit eb18cb83d13d664896468d200d9dc353da13c561) --- source3/configure.in | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 9fffe7c3c6..d07baf1210 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -14,6 +14,15 @@ AC_ENABLE_SHARED # ones... AC_PREFIX_DEFAULT(/usr/local/samba) +lockdir="\${VARDIR}/locks" +piddir="\${VARDIR}/locks" +mandir="\${prefix}/man" +logfilebase="\${VARDIR}" +privatedir="\${prefix}/private" +libdir="\${prefix}/lib" +configdir="\${LIBDIR}" +swatdir="\${prefix}/swat" + AC_ARG_WITH(fhs, [ --with-fhs Use FHS-compliant paths (default=no)], [ case "$withval" in @@ -25,16 +34,12 @@ AC_ARG_WITH(fhs, logfilebase="\${VARDIR}/log/samba" privatedir="\${CONFIGDIR}/private" libdir="\${prefix}/lib/samba" - swatdir="\${DATADIR}/samba/swat", - configdir="\${LIBDIR}" - logfilebase="\${VARDIR}" - lockdir="\${VARDIR}/locks" - piddir="\${VARDIR}/locks" - privatedir="\${prefix}/private" - swatdir="\${prefix}/swat" + swatdir="\${LIBDIR}/samba/swat" ;; esac]) +lmhostsfile="\${CONFIGDIR}/lmhosts" + ################################################# # set private directory location AC_ARG_WITH(privatedir, -- cgit From eebc94d84af736bb1fdd8e0c511237b0da978e7a Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 1 Mar 2004 16:10:28 +0000 Subject: Ok here it is my latest work on privileges This patch add privilege support for samba Currently it is implemented only for tdbsam backend but estending it to other sam backends is straightforward. I must make a big thank to JFM for his teachings on the matter and the functions at the base of this work. At thye moment only samr_create_user honours SeAddUsersPrivilege and SeMachineAccountPrivilege to permit any user to add machines and/or users to the server. The command "net priv" has been provided to manipulate the privileges database. There are still many things to do (like support in "net rpc vampire") but the working core is here. Feel free to comment/extend on this work. Of course I will deny that any bug may affect this code :-) Simo. This patch adds also my patch about add share command enhancements. (This used to be commit 7a78c3605e203bd8e0d7ae244605f076a5d0b0bc) --- source3/Makefile.in | 2 +- source3/auth/auth_util.c | 22 +++ source3/groupdb/mapping.c | 11 -- source3/include/auth.h | 1 + source3/include/includes.h | 4 +- source3/include/passdb.h | 20 +++ source3/include/privileges.h | 47 ++++- source3/include/smb.h | 3 + source3/lib/privileges.c | 79 ++++++++- source3/param/loadparm.c | 2 +- source3/passdb/pdb_interface.c | 157 +++++++++++++++++ source3/passdb/pdb_tdb.c | 353 +++++++++++++++++++++++++++++++++++++ source3/rpc_server/srv_lsa_nt.c | 4 +- source3/rpc_server/srv_pipe_hnd.c | 2 + source3/rpc_server/srv_samr_nt.c | 72 +++++--- source3/rpc_server/srv_srvsvc_nt.c | 70 ++++++-- source3/sam/gums.c | 63 ------- source3/smbd/chgpasswd.c | 2 +- source3/smbd/conn.c | 8 + source3/smbd/password.c | 6 + source3/smbd/sec_ctx.c | 27 ++- source3/smbd/service.c | 4 + source3/smbd/uid.c | 18 +- source3/utils/net.c | 1 + 24 files changed, 838 insertions(+), 140 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 25a0e45f05..5792b00264 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -514,7 +514,7 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \ utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \ utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \ utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \ - utils/net_status.o + utils/net_status.o utils/net_privileges.o NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 4a23593936..018d3b1851 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -826,6 +826,23 @@ static NTSTATUS add_user_groups(auth_serversupplied_info **server_info, return nt_status; } +/*************************************************************************** +Fill a server_info struct from a SAM_ACCOUNT with its privileges +***************************************************************************/ + +static NTSTATUS add_privileges(auth_serversupplied_info **server_info) +{ + PRIVILEGE_SET *privs = NULL; + + init_privilege(&privs); + if (!pdb_get_privilege_set((*server_info)->ptok, privs)) + return NT_STATUS_UNSUCCESSFUL; + + (*server_info)->privs = privs; + + return NT_STATUS_OK; +} + /*************************************************************************** Make (and fill) a user_info struct from a SAM_ACCOUNT ***************************************************************************/ @@ -860,6 +877,11 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, return nt_status; } + if (!NT_STATUS_IS_OK(nt_status = add_privileges(server_info))) { + free_server_info(server_info); + return nt_status; + } + (*server_info)->sam_fill_level = SAM_FILL_ALL; DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n", pdb_get_username(sampass), diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index c153ff258d..ef0708b888 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -29,17 +29,6 @@ static TDB_CONTEXT *tdb; /* used for driver files */ #define GROUP_PREFIX "UNIXGROUP/" #define ALIASMEM_PREFIX "ALIASMEMBERS/" -PRIVS privs[] = { - {SE_PRIV_NONE, "no_privs", "No privilege" }, /* this one MUST be first */ - {SE_PRIV_ADD_MACHINES, "SeMachineAccountPrivilege", "Add workstations to the domain" }, - {SE_PRIV_SEC_PRIV, "SeSecurityPrivilege", "Manage the audit logs" }, - {SE_PRIV_TAKE_OWNER, "SeTakeOwnershipPrivilege", "Take ownership of file" }, - {SE_PRIV_ADD_USERS, "SaAddUsers", "Add users to the domain - Samba" }, - {SE_PRIV_PRINT_OPERATOR, "SaPrintOp", "Add or remove printers - Samba" }, - {SE_PRIV_ALL, "SaAllPrivs", "all privileges" } -}; - - /**************************************************************************** dump the mapping group mapping to a text file ****************************************************************************/ diff --git a/source3/include/auth.h b/source3/include/auth.h index ecf4d539d8..27cdc1e3f5 100644 --- a/source3/include/auth.h +++ b/source3/include/auth.h @@ -86,6 +86,7 @@ typedef struct auth_serversupplied_info /* NT group information taken from the info3 structure */ NT_USER_TOKEN *ptok; + PRIVILEGE_SET *privs; DATA_BLOB nt_session_key; DATA_BLOB lm_session_key; diff --git a/source3/include/includes.h b/source3/include/includes.h index db060907e4..a594e309df 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -783,6 +783,8 @@ extern int errno; #include "version.h" +#include "privileges.h" + #include "smb.h" #include "nameserv.h" @@ -791,8 +793,6 @@ extern int errno; #include "byteorder.h" -#include "privileges.h" - #include "rpc_creds.h" #include "mapping.h" diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 668bbcc2de..d471eb53f3 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -362,6 +362,16 @@ typedef struct pdb_context NTSTATUS (*pdb_update_trust_passwd)(struct pdb_context *context, SAM_TRUST_PASSWD* trust); NTSTATUS (*pdb_delete_trust_passwd)(struct pdb_context *context, SAM_TRUST_PASSWD* trust); + + /* privileges functions */ + + NTSTATUS (*pdb_add_sid_to_privilege)(struct pdb_context *context, const char *priv_name, const DOM_SID *sid); + + NTSTATUS (*pdb_remove_sid_from_privilege)(struct pdb_context *context, const char *priv_name, const DOM_SID *sid); + + NTSTATUS (*pdb_get_privilege_set)(struct pdb_context *context, NT_USER_TOKEN *token, PRIVILEGE_SET *privs); + + NTSTATUS (*pdb_get_privilege_entry)(struct pdb_context *context, const char *privname, char **sid_list); void (*free_fn)(struct pdb_context **); @@ -467,6 +477,16 @@ typedef struct pdb_methods NTSTATUS (*delete_trust_passwd)(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust); + /* privileges functions */ + + NTSTATUS (*add_sid_to_privilege)(struct pdb_methods *methods, const char *priv_name, const DOM_SID *sid); + + NTSTATUS (*remove_sid_from_privilege)(struct pdb_methods *methods, const char *priv_name, const DOM_SID *sid); + + NTSTATUS (*get_privilege_set)(struct pdb_methods *methods, NT_USER_TOKEN *token, PRIVILEGE_SET *privs); + + NTSTATUS (*get_privilege_entry)(struct pdb_methods *methods, const char *privname, char **sid_list); + } PDB_METHODS; typedef NTSTATUS (*pdb_init_function)(struct pdb_context *, diff --git a/source3/include/privileges.h b/source3/include/privileges.h index b7e1b44c2a..289afa234e 100644 --- a/source3/include/privileges.h +++ b/source3/include/privileges.h @@ -23,15 +23,39 @@ #ifndef PRIVILEGES_H #define PRIVILEGES_H -#define PRIV_ALL_INDEX 5 +#define PRIV_ALL_INDEX 30 -#define SE_PRIV_NONE 0x0000 -#define SE_PRIV_ADD_MACHINES 0x0006 -#define SE_PRIV_SEC_PRIV 0x0008 -#define SE_PRIV_TAKE_OWNER 0x0009 -#define SE_PRIV_ADD_USERS 0xff01 -#define SE_PRIV_PRINT_OPERATOR 0xff03 -#define SE_PRIV_ALL 0xffff +#define SE_NONE 0 +#define SE_ASSIGN_PRIMARY_TOKEN 1 +#define SE_CREATE_TOKEN 2 +#define SE_LOCK_MEMORY 3 +#define SE_INCREASE_QUOTA 4 +#define SE_UNSOLICITED_INPUT 5 +#define SE_MACHINE_ACCOUNT 6 +#define SE_TCB 7 +#define SE_SECURITY 8 +#define SE_TAKE_OWNERSHIP 9 +#define SE_LOAD_DRIVER 10 +#define SE_SYSTEM_PROFILE 11 +#define SE_SYSTEM_TIME 12 +#define SE_PROF_SINGLE_PROCESS 13 +#define SE_INC_BASE_PRIORITY 14 +#define SE_CREATE_PAGEFILE 15 +#define SE_CREATE_PERMANENT 16 +#define SE_BACKUP 17 +#define SE_RESTORE 18 +#define SE_SHUTDOWN 19 +#define SE_DEBUG 20 +#define SE_AUDIT 21 +#define SE_SYSTEM_ENVIRONMENT 22 +#define SE_CHANGE_NOTIFY 23 +#define SE_REMOTE_SHUTDOWN 24 +#define SE_UNDOCK 25 +#define SE_SYNC_AGENT 26 +#define SE_ENABLE_DELEGATION 27 +#define SE_PRINT_OPERATOR 28 +#define SE_ADD_USERS 29 +#define SE_ALL_PRIVS 0xffff #define PR_NONE 0x0000 #define PR_LOG_ON_LOCALLY 0x0001 @@ -39,6 +63,11 @@ #define PR_LOG_ON_BATCH_JOB 0x0004 #define PR_LOG_ON_SERVICE 0x0010 +#ifndef _BOOL +typedef int BOOL; +#define _BOOL /* So we don't typedef BOOL again in vfs.h */ +#endif + typedef struct LUID { uint32 low; @@ -49,7 +78,7 @@ typedef struct LUID_ATTR { LUID luid; uint32 attr; -} LUID_ATTR ; +} LUID_ATTR; typedef struct privilege_set { diff --git a/source3/include/smb.h b/source3/include/smb.h index 5cd5e71f74..ab6f4c70d6 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -500,6 +500,7 @@ typedef struct connection_struct int ngroups; gid_t *groups; NT_USER_TOKEN *nt_user_token; + PRIVILEGE_SET *privs; time_t lastused; BOOL used; @@ -519,6 +520,7 @@ struct current_user int ngroups; gid_t *groups; NT_USER_TOKEN *nt_user_token; + PRIVILEGE_SET *privs; }; /* Defines for the sent_oplock_break field above. */ @@ -1546,6 +1548,7 @@ typedef struct user_struct gid_t *groups; NT_USER_TOKEN *nt_user_token; + PRIVILEGE_SET *privs; DATA_BLOB session_key; diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c index b9d4df301d..4bcf5e3b36 100644 --- a/source3/lib/privileges.c +++ b/source3/lib/privileges.c @@ -26,6 +26,43 @@ #define ALLOC_CHECK(ptr, err, label, str) do { if ((ptr) == NULL) { DEBUG(0, ("%s: out of memory!\n", str)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0) #define NTSTATUS_CHECK(err, label, str1, str2) do { if (!NT_STATUS_IS_OK(err)) { DEBUG(0, ("%s: %s failed!\n", str1, str2)); } } while(0) + +PRIVS privs[] = { + {SE_NONE, "no_privs", "No privilege"}, /* this one MUST be first */ + {SE_CREATE_TOKEN, "SeCreateTokenPrivilege", "Create Token"}, + {SE_ASSIGN_PRIMARY_TOKEN, "SeAssignPrimaryTokenPrivilege", "Assign Primary Token"}, + {SE_LOCK_MEMORY, "SeLockMemoryPrivilege", "Lock Memory"}, + {SE_INCREASE_QUOTA, "SeIncreaseQuotaPrivilege", "Increase Quota"}, + {SE_UNSOLICITED_INPUT, "eUnsolicitedInputPrivilege", "Unsolicited Input"}, + {SE_MACHINE_ACCOUNT, "SeMachineAccountPrivilege", "Can add Machine Accounts to the Domain"}, + {SE_TCB, "SeTcbPrivilege", "TCB"}, + {SE_SECURITY, "SeSecurityPrivilege", "Security Privilege"}, + {SE_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege", "Take Ownership Privilege"}, + {SE_LOAD_DRIVER, "SeLocalDriverPrivilege", "Local Driver Privilege"}, + {SE_SYSTEM_PROFILE, "SeSystemProfilePrivilege", "System Profile Privilege"}, + {SE_SYSTEM_TIME, "SeSystemtimePrivilege", "System Time"}, + {SE_PROF_SINGLE_PROCESS, "SeProfileSingleProcessPrivilege", "Profile Single Process Privilege"}, + {SE_INC_BASE_PRIORITY, "SeIncreaseBasePriorityPrivilege", "Increase Base Priority Privilege"}, + {SE_CREATE_PAGEFILE, "SeCreatePagefilePrivilege", "Create Pagefile Privilege"}, + {SE_CREATE_PERMANENT, "SeCreatePermanentPrivilege", "Create Permanent"}, + {SE_BACKUP, "SeBackupPrivilege", "Backup Privilege"}, + {SE_RESTORE, "SeRestorePrivilege", "Restore Privilege"}, + {SE_SHUTDOWN, "SeShutdownPrivilege", "Shutdown Privilege"}, + {SE_DEBUG, "SeDebugPrivilege", "Debug Privilege"}, + {SE_AUDIT, "SeAuditPrivilege", "Audit"}, + {SE_SYSTEM_ENVIRONMENT, "SeSystemEnvironmentPrivilege", "System Environment Privilege"}, + {SE_CHANGE_NOTIFY, "SeChangeNotifyPrivilege", "Change Notify"}, + {SE_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Remote Shutdown Privilege"}, + {SE_UNDOCK, "SeUndockPrivilege", "Undock"}, + {SE_SYNC_AGENT, "SeSynchronizationAgentPrivilege", "Synchronization Agent"}, + {SE_ENABLE_DELEGATION, "SeEnableDelegationPrivilege", "Enable Delegation"}, + {SE_PRINT_OPERATOR, "SePrintOperatorPrivilege", "Printer Operator"}, + {SE_ADD_USERS, "SeAddUsersPrivilege", "Add Users"}, + {SE_ALL_PRIVS, "SeAllPrivileges", "All Privileges"} +}; + + + /**************************************************************************** Check if a user is a mapped group. @@ -170,6 +207,27 @@ done: return ret; } +NTSTATUS add_privilege_by_name(PRIVILEGE_SET *priv_set, const char *name) +{ + int e; + + for (e = 0; privs[e].se_priv != SE_ALL_PRIVS; e++) { + if (StrCaseCmp(privs[e].priv, name) == 0) { + LUID_ATTR la; + + la.attr = 0; + la.luid.high = 0; + la.luid.low = privs[e].se_priv; + + return add_privilege(priv_set, la); + } + } + + DEBUG(1, ("add_privilege_by_name: No Such Privilege Found (%s)\n", name)); + + return NT_STATUS_UNSUCCESSFUL; +} + /**************************************************************************** add all the privileges to a privilege array ****************************************************************************/ @@ -182,15 +240,15 @@ NTSTATUS add_all_privilege(PRIVILEGE_SET *priv_set) set.luid.high = 0; /* TODO: set a proper list of privileges */ - set.luid.low = SE_PRIV_ADD_USERS; + set.luid.low = SE_ADD_USERS; result = add_privilege(priv_set, set); NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege"); - set.luid.low = SE_PRIV_ADD_MACHINES; + set.luid.low = SE_MACHINE_ACCOUNT; result = add_privilege(priv_set, set); NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege"); - set.luid.low = SE_PRIV_PRINT_OPERATOR; + set.luid.low = SE_PRINT_OPERATOR; result = add_privilege(priv_set, set); NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege"); @@ -329,7 +387,7 @@ NTSTATUS dup_priv_set(PRIVILEGE_SET *new_priv_set, PRIVILEGE_SET *priv_set) old_set = priv_set->set; - new_set = (LUID_ATTR *)talloc(new_priv_set->mem_ctx, (priv_set->count - 1) * (sizeof(LUID_ATTR))); + new_set = (LUID_ATTR *)talloc(new_priv_set->mem_ctx, (priv_set->count) * (sizeof(LUID_ATTR))); ALLOC_CHECK(new_set, ret, done, "dup_priv_set"); for (i=0; i < priv_set->count; i++) { @@ -348,3 +406,16 @@ NTSTATUS dup_priv_set(PRIVILEGE_SET *new_priv_set, PRIVILEGE_SET *priv_set) done: return ret; } + + +NTSTATUS user_has_privilege(struct current_user *user, uint32 privilege) +{ + LUID_ATTR set; + + set.attr = 0; + set.luid.high = 0; + set.luid.low = privilege; + + return check_priv_in_privilege(user->privs, set); +} + diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index ae9d3ae945..58f4919465 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -3857,7 +3857,7 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults, if (iServiceIndex >= 0) bRetval = service_ok(iServiceIndex); - if (lp_config_backend()) { + if (*(lp_config_backend())) { modconf_init(lp_config_backend()); modconf_load(do_section, do_parameter); } diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 2005885c45..180db58c2d 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -587,6 +587,86 @@ static NTSTATUS context_delete_trust_passwd(struct pdb_context *context, return trust->methods->delete_trust_passwd(trust->methods, trust); } +static NTSTATUS context_add_sid_to_privilege(struct pdb_context *context, const char *priv_name, const DOM_SID *sid) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + struct pdb_methods *curmethods; + if ((!context)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + curmethods = context->pdb_methods; + while (curmethods){ + if (NT_STATUS_IS_OK(ret = curmethods->add_sid_to_privilege(curmethods, priv_name, sid))) { + return ret; + } + curmethods = curmethods->next; + } + + return ret; +} + +static NTSTATUS context_remove_sid_from_privilege(struct pdb_context *context, const char *priv_name, const DOM_SID *sid) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + struct pdb_methods *curmethods; + if ((!context)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + curmethods = context->pdb_methods; + while (curmethods){ + if (NT_STATUS_IS_OK(ret = curmethods->remove_sid_from_privilege(curmethods, priv_name, sid))) { + return ret; + } + curmethods = curmethods->next; + } + + return ret; +} + +static NTSTATUS context_get_privilege_set(struct pdb_context *context, NT_USER_TOKEN *token, PRIVILEGE_SET *privset) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + struct pdb_methods *curmethods; + if ((!context)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + curmethods = context->pdb_methods; + while (curmethods){ + if (NT_STATUS_IS_OK(ret = curmethods->get_privilege_set(curmethods, token, privset))) { + return ret; + } + curmethods = curmethods->next; + } + + return ret; +} + +static NTSTATUS context_get_privilege_entry(struct pdb_context *context, const char *privname, char **sid_list) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + struct pdb_methods *curmethods; + if ((!context)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + curmethods = context->pdb_methods; + while (curmethods){ + if (NT_STATUS_IS_OK(ret = curmethods->get_privilege_entry(curmethods, privname, sid_list))) { + return ret; + } + curmethods = curmethods->next; + } + + return ret; +} + /****************************************************************** Free and cleanup a pdb context, any associated data and anything that the attached modules might have associated. @@ -711,6 +791,10 @@ static NTSTATUS make_pdb_context(struct pdb_context **context) (*context)->pdb_add_trust_passwd = context_add_trust_passwd; (*context)->pdb_update_trust_passwd = context_update_trust_passwd; (*context)->pdb_delete_trust_passwd = context_delete_trust_passwd; + (*context)->pdb_add_sid_to_privilege = context_add_sid_to_privilege; + (*context)->pdb_remove_sid_from_privilege = context_remove_sid_from_privilege; + (*context)->pdb_get_privilege_set = context_get_privilege_set; + (*context)->pdb_get_privilege_entry = context_get_privilege_entry; (*context)->free_fn = free_pdb_context; @@ -1072,6 +1156,54 @@ BOOL pdb_enum_alias_memberships(const DOM_SID *sid, aliases, num)); } +BOOL pdb_add_sid_to_privilege(char *priv_name, DOM_SID *sid) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context-> + pdb_add_sid_to_privilege(pdb_context, priv_name, sid)); +} + +BOOL pdb_remove_sid_from_privilege(char *priv_name, DOM_SID *sid) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context-> + pdb_remove_sid_from_privilege(pdb_context, priv_name, sid)); +} + +BOOL pdb_get_privilege_set(NT_USER_TOKEN *token, PRIVILEGE_SET *privset) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context-> + pdb_get_privilege_set(pdb_context, token, privset)); +} + +BOOL pdb_get_privilege_entry(const char *privname, char **sid_list) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context-> + pdb_get_privilege_entry(pdb_context, privname, sid_list)); +} + /*************************************************************** Initialize the static context (at smbd startup etc). @@ -1155,6 +1287,26 @@ static NTSTATUS pdb_default_delete_trust_passwd(struct pdb_methods *methods, con return NT_STATUS_NOT_IMPLEMENTED; } +static NTSTATUS pdb_default_add_sid_to_privilege(struct pdb_methods *methods, const char *priv_name, const DOM_SID *sid) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_default_remove_sid_from_privilege(struct pdb_methods *methods, const char *priv_name, const DOM_SID *sid) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_default_get_privilege_set(struct pdb_methods *methods, NT_USER_TOKEN *token, PRIVILEGE_SET *privset) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_default_get_privilege_entry(struct pdb_methods *methods, const char *privname, char **sid_list) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) { @@ -1193,5 +1345,10 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) (*methods)->update_trust_passwd = pdb_default_update_trust_passwd; (*methods)->delete_trust_passwd = pdb_default_delete_trust_passwd; + (*methods)->add_sid_to_privilege = pdb_default_add_sid_to_privilege; + (*methods)->remove_sid_from_privilege = pdb_default_remove_sid_from_privilege; + (*methods)->get_privilege_set = pdb_default_get_privilege_set; + (*methods)->get_privilege_entry = pdb_default_get_privilege_entry; + return NT_STATUS_OK; } diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index f54463e158..39de791b07 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -42,6 +42,7 @@ static int tdbsam_debug_level = DBGC_ALL; #define PASSDB_FILE_NAME "passdb.tdb" #define USERPREFIX "USER_" #define RIDPREFIX "RID_" +#define PRIVPREFIX "PRIV_" #define tdbsamver_t int32 struct tdbsam_privates { @@ -895,6 +896,354 @@ static NTSTATUS tdbsam_delete_trust_passwd(struct pdb_methods *methods, const SA } +/*************************************************************************** + Add sid to privilege +****************************************************************************/ + +static NTSTATUS tdbsam_add_sid_to_privilege(struct pdb_methods *my_methods, const char *priv_name, const DOM_SID *sid) +{ + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + TDB_CONTEXT *pwd_tdb = NULL; + TDB_DATA key, data; + fstring keystr; + fstring name; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + fstring sid_str; + char *sid_list = NULL, *s = NULL; + size_t str_size; + int flag; + + /* invalidate the existing TDB iterator if it is open */ + + if (tdb_state->passwd_tdb) { + tdb_close(tdb_state->passwd_tdb); + tdb_state->passwd_tdb = NULL; + } + + /* open the account TDB passwd*/ + + pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT); + + if (!pwd_tdb) { + DEBUG(0, ("tdb_add_sid_to_privilege: Unable to open TDB passwd (%s)!\n", + tdb_state->tdbsam_location)); + return NT_STATUS_UNSUCCESSFUL; + } + + /* setup the PRIV index key */ + fstrcpy(name, priv_name); + strlower_m(name); + + slprintf(keystr, sizeof(keystr)-1, "%s%s", PRIVPREFIX, name); + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; + + /* check if the privilege already exist in the database */ + + /* get the record */ + data = tdb_fetch (pwd_tdb, key); + + if (data.dptr) { + /* check the list is not empty */ + if (*(data.dptr)) { + sid_list = strdup(data.dptr); + if (!sid_list) { + DEBUG(0, ("tdbsam_add_sid_to_privilege: Out of Memory!\n")); + goto done; + } + } + SAFE_FREE(data.dptr); + + flag = TDB_MODIFY; + } else { + /* if privilege does not exist create one */ + flag = TDB_INSERT; + } + + /* add the given sid */ + sid_to_string(sid_str, sid); + + if (sid_list) { + str_size = strlen(sid_list) + strlen(sid_str) + 2; + s = realloc(sid_list, str_size); + if (!s) { + DEBUG(0, ("tdbsam_add_sid_to_privilege: Out of Memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; + } + sid_list = s; + s = &sid_list[strlen(sid_list)]; + snprintf(s, strlen(sid_str) + 2, ",%s", sid_str); + + } else { + sid_list = strdup(sid_str); + if (!sid_list) { + DEBUG(0, ("tdbsam_add_sid_to_privilege: Out of Memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; + } + + } + + /* copy the PRIVILEGE struct into a BYTE buffer for storage */ + data.dsize = strlen(sid_list) + 1; + data.dptr = sid_list; + + /* add the account */ + if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) { + DEBUG(0, ("Unable to modify passwd TDB!")); + DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb))); + DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr)); + goto done; + } + + ret = NT_STATUS_OK; + +done: + /* cleanup */ + tdb_close (pwd_tdb); + SAFE_FREE(sid_list); + + return (ret); +} + +/*************************************************************************** + Reomve sid to privilege +****************************************************************************/ + +static NTSTATUS tdbsam_remove_sid_from_privilege(struct pdb_methods *my_methods, const char *priv_name, const DOM_SID *sid) +{ + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + TDB_CONTEXT *pwd_tdb = NULL; + TDB_DATA key, data; + fstring keystr; + fstring name; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + fstring sid_str; + char *sid_list = NULL, *s = NULL; + + /* invalidate the existing TDB iterator if it is open */ + + if (tdb_state->passwd_tdb) { + tdb_close(tdb_state->passwd_tdb); + tdb_state->passwd_tdb = NULL; + } + + /* open the account TDB passwd*/ + + pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT); + + if (!pwd_tdb) { + DEBUG(0, ("tdbsam_remove_sid_from_privilege: Unable to open TDB passwd (%s)!\n", + tdb_state->tdbsam_location)); + return NT_STATUS_UNSUCCESSFUL; + } + + /* setup the PRIV index key */ + fstrcpy(name, priv_name); + strlower_m(name); + + slprintf(keystr, sizeof(keystr)-1, "%s%s", PRIVPREFIX, name); + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; + + /* check if the privilege already exist in the database */ + + /* get the record */ + data = tdb_fetch (pwd_tdb, key); + + /* if privilege does not exist, just leave */ + if (!data.dptr) { + ret = NT_STATUS_OK; + goto done; + } + + if (data.dptr) { + sid_list = strdup(data.dptr); + if (!sid_list) { + DEBUG(0, ("tdbsam_remove_sid_from_privilege: Out of Memory!\n")); + goto done; + } + SAFE_FREE(data.dptr); + } + + /* remove the given sid */ + sid_to_string(sid_str, sid); + + s = strstr(sid_list, sid_str); + if (s) { + char *p; + p = strstr(s, ","); + if (p) { + size_t l = strlen(sid_list) + 1 - (s - sid_list); + memmove(s, ++p, l); + } else { + if (s != sid_list) + s--; + *s = '\0'; + } + } else { + /* sid not found */ + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* copy the PRIVILEGE struct into a BYTE buffer for storage */ + data.dsize = strlen(sid_list) + 1; + data.dptr = sid_list; + + /* add the account */ + if (tdb_store(pwd_tdb, key, data, TDB_MODIFY) != TDB_SUCCESS) { + DEBUG(0, ("Unable to modify passwd TDB!")); + DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb))); + DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr)); + goto done; + } + + ret = NT_STATUS_OK; + +done: + /* cleanup */ + tdb_close (pwd_tdb); + SAFE_FREE(sid_list); + + return (ret); +} + +/*************************************************************************** + get the privilege list for the given token +****************************************************************************/ + +struct priv_traverse { + char **sid_list; + PRIVILEGE_SET *privset; +}; + +static int tdbsam_traverse_privilege(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) +{ + struct priv_traverse *pt = (struct priv_traverse *)state; + int prefixlen = strlen(PRIVPREFIX); + + if (strncmp(key.dptr, PRIVPREFIX, prefixlen) == 0) { + + /* add to privilege_set if any of the sid in the token + * is contained in the privilege */ + int i; + + for(i=0; pt->sid_list[i] != NULL; i++) { + char *c, *s; + int len; + + s = data.dptr; + while (c = strchr(s, ',')) { + len = MAX((c - s), strlen(pt->sid_list[i])); + if (strncmp(s, pt->sid_list[i], len) == 0) { + DEBUG(10, ("sid [%s] found in users sid list\n", pt->sid_list[i])); + DEBUG(10, ("adding privilege [%s] to the users privilege list\n", &(key.dptr[prefixlen]))); + add_privilege_by_name(pt->privset, &(key.dptr[prefixlen])); + return 0; + } + s = c + 1; + } + len = MAX(strlen(s), strlen(pt->sid_list[i])); + if (strncmp(s, pt->sid_list[i], len) == 0) { + DEBUG(10, ("sid [%s] found in users sid list\n", pt->sid_list[i])); + DEBUG(10, ("adding privilege [%s] to the users privilege list\n", &(key.dptr[prefixlen]))); + add_privilege_by_name(pt->privset, &(key.dptr[prefixlen])); + return 0; + } + } + } + + return 0; +} + +static NTSTATUS tdbsam_get_privilege_set(struct pdb_methods *my_methods, NT_USER_TOKEN *token, PRIVILEGE_SET *privset) +{ + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + TDB_CONTEXT *pwd_tdb = NULL; + struct priv_traverse pt; + fstring sid_str; + char **sid_list; + int i; + + if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY ))) + return NT_STATUS_UNSUCCESSFUL; + + sid_list = (char **)malloc(sizeof(char *) * (token->num_sids + 1)); + for (i = 0; i < token->num_sids; i++) { + sid_to_string(sid_str, &token->user_sids[i]); + sid_list[i] = strdup(sid_str); + if ( ! sid_list[i]) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } + } + sid_list[i] = NULL; + + pt.sid_list = sid_list; + pt.privset = privset; + tdb_traverse(pwd_tdb, tdbsam_traverse_privilege, &pt); + + ret = NT_STATUS_OK; + +done: + i = 0; + while (sid_list[i]) { + free(sid_list[i]); + i++; + } + free(sid_list); + + tdb_close(pwd_tdb); + + return ret; +} + +static NTSTATUS tdbsam_get_privilege_entry(struct pdb_methods *my_methods, const char *privname, char **sid_list) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + TDB_CONTEXT *pwd_tdb = NULL; + TDB_DATA key, data; + fstring name; + fstring keystr; + + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + + if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY))) + return ret; + + /* setup the PRIV index key */ + fstrcpy(name, privname); + strlower_m(name); + + slprintf(keystr, sizeof(keystr)-1, "%s%s", PRIVPREFIX, name); + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; + + data = tdb_fetch(pwd_tdb, key); + if (!data.dptr) + goto done; + + *sid_list = strdup(data.dptr); + SAFE_FREE(data.dptr); + + if (!*sid_list) + goto done; + + ret = NT_STATUS_OK; +done: + tdb_close(pwd_tdb); + return ret; +} + + + + + + + static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; @@ -919,6 +1268,10 @@ static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_meth (*pdb_method)->add_trust_passwd = tdbsam_add_trust_passwd; (*pdb_method)->update_trust_passwd = tdbsam_update_trust_passwd; (*pdb_method)->delete_trust_passwd = tdbsam_delete_trust_passwd; + (*pdb_method)->add_sid_to_privilege = tdbsam_add_sid_to_privilege; + (*pdb_method)->remove_sid_from_privilege = tdbsam_remove_sid_from_privilege; + (*pdb_method)->get_privilege_set = tdbsam_get_privilege_set; + (*pdb_method)->get_privilege_entry = tdbsam_get_privilege_entry; tdb_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct tdbsam_privates)); diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index aa933f9d0d..1e3c6c2a9d 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -819,10 +819,10 @@ NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, L DEBUG(10,("_lsa_priv_get_dispname: %s", name_asc)); - while (privs[i].se_priv!=SE_PRIV_ALL && strcmp(name_asc, privs[i].priv)) + while (privs[i].se_priv!=SE_ALL_PRIVS && strcmp(name_asc, privs[i].priv)) i++; - if (privs[i].se_priv!=SE_PRIV_ALL) { + if (privs[i].se_priv!=SE_ALL_PRIVS) { DEBUG(10,(": %s\n", privs[i].description)); init_unistr2(&r_u->desc, privs[i].description, UNI_FLAGS_NONE); init_uni_hdr(&r_u->hdr_desc, &r_u->desc); diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 514c22d471..64ca8388d7 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -344,6 +344,8 @@ static void *make_internal_rpc_pipe_p(char *pipe_name, if (vuser) { p->session_key = data_blob(vuser->session_key.data, vuser->session_key.length); p->pipe_user.nt_user_token = dup_nt_token(vuser->nt_user_token); + init_privilege(&p->pipe_user.privs); + dup_priv_set(p->pipe_user.privs, vuser->privs); } /* diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index b50d44d9e3..1959674f0a 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -40,6 +40,7 @@ extern rid_name domain_group_rids[]; extern rid_name domain_alias_rids[]; extern rid_name builtin_alias_rids[]; +extern PRIVS privs[]; typedef struct _disp_info { BOOL user_dbloaded; @@ -2137,7 +2138,15 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) { - return nt_status; + if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), SE_MACHINE_ACCOUNT))) { + DEBUG(3, ("_samr_create_user: User should be denied access but was overridden by %s\n", privs[SE_MACHINE_ACCOUNT].priv)); + } else { + if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), SE_ADD_USERS))) { + DEBUG(3, ("_samr_create_user: User should be denied access but was overridden by %s\n", privs[SE_ADD_USERS].priv)); + } else { + return nt_status; + } + } } if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) { @@ -2200,6 +2209,33 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA /* the passdb lookup has failed; check to see if we need to run the add user/machine script */ + + /* + * we can't check both the ending $ and the acb_info. + * + * UserManager creates trust accounts (ending in $, + * normal that hidden accounts) with the acb_info equals to ACB_NORMAL. + * JFM, 11/29/2001 + */ + if (account[strlen(account)-1] == '$') { + if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), SE_MACHINE_ACCOUNT)) || geteuid() == 0) { + DEBUG(3, ("user [%s] has been granted Add Machines privilege!\n", p->user_name)); + become_root(); + pstrcpy(add_script, lp_addmachine_script()); + } else { + DEBUG(3, ("user [%s] doesn't have Add Machines privilege!\n", p->user_name)); + return NT_STATUS_ACCESS_DENIED; + } + } else { + if (NT_STATUS_IS_OK(user_has_privilege(&(p->pipe_user), SE_ADD_USERS)) || geteuid() == 0) { + DEBUG(3, ("user [%s] has been granted Add Users privilege!\n", p->user_name)); + become_root(); + pstrcpy(add_script, lp_adduser_script()); + } else { + DEBUG(3, ("user [%s] doesn't have Add Users privilege!\n", p->user_name)); + return NT_STATUS_ACCESS_DENIED; + } + } pw = Get_Pwnam(account); @@ -2215,17 +2251,6 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA *********************************************************************/ if ( !pw ) { - /* - * we can't check both the ending $ and the acb_info. - * - * UserManager creates trust accounts (ending in $, - * normal that hidden accounts) with the acb_info equals to ACB_NORMAL. - * JFM, 11/29/2001 - */ - if (account[strlen(account)-1] == '$') - pstrcpy(add_script, lp_addmachine_script()); - else - pstrcpy(add_script, lp_adduser_script()); if (*add_script) { int add_ret; @@ -2235,7 +2260,7 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA } else /* no add user script -- ask winbindd to do it */ { - if ( !winbind_create_user( account, &new_rid ) ) { + if (!winbind_create_user(account, &new_rid)) { DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n", account)); } @@ -2246,15 +2271,16 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA /* implicit call to getpwnam() next. we have a valid SID coming out of this call */ if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) ) - return nt_status; + goto done; pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED); if (!pdb_add_sam_account(sam_pass)) { pdb_free_sam(&sam_pass); - DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n", + DEBUG(0, ("could not add user/computer %s to passdb !?\n", account)); - return NT_STATUS_ACCESS_DENIED; + nt_status = NT_STATUS_ACCESS_DENIED; + goto done; } /* Get the user's SID */ @@ -2265,13 +2291,14 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA if (!NT_STATUS_IS_OK(nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, "_samr_create_user"))) { - return nt_status; + goto done; } /* associate the user's SID with the new handle. */ if ((info = get_samr_info_by_sid(&sid)) == NULL) { pdb_free_sam(&sam_pass); - return NT_STATUS_NO_MEMORY; + nt_status = NT_STATUS_NO_MEMORY; + goto done; } ZERO_STRUCTP(info); @@ -2281,7 +2308,8 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) { pdb_free_sam(&sam_pass); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + goto done; } r_u->user_rid=pdb_get_user_rid(sam_pass); @@ -2290,7 +2318,11 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA pdb_free_sam(&sam_pass); - return NT_STATUS_OK; + nt_status = NT_STATUS_OK; + +done: + unbecome_root(); + return nt_status; } /******************************************************************* diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 40d3a43bef..7487e106bc 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -1405,10 +1405,7 @@ WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, S static char *valid_share_pathname(char *dos_pathname) { - pstring saved_pathname; - pstring unix_pathname; char *ptr; - int ret; /* Convert any '\' paths to '/' */ unix_format(dos_pathname); @@ -1423,21 +1420,29 @@ static char *valid_share_pathname(char *dos_pathname) if (*ptr != '/') return NULL; + return ptr; +} + +static BOOL exist_share_pathname(char *unix_pathname) +{ + pstring saved_pathname; + int ret; + /* Can we cd to it ? */ /* First save our current directory. */ if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL) return False; - pstrcpy(unix_pathname, ptr); - ret = chdir(unix_pathname); /* We *MUST* be able to chdir back. Abort if we can't. */ if (chdir(saved_pathname) == -1) smb_panic("valid_share_pathname: Unable to restore current directory.\n"); - return (ret != -1) ? ptr : NULL; + if (ret == -1) return False; + + return True; } /******************************************************************* @@ -1454,7 +1459,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S int type; int snum; int ret; - char *ptr; + char *path; SEC_DESC *psd = NULL; DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__)); @@ -1549,12 +1554,12 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S return WERR_ACCESS_DENIED; /* Check if the pathname is valid. */ - if (!(ptr = valid_share_pathname( pathname ))) + if (!(path = valid_share_pathname( pathname ))) return WERR_OBJECT_PATH_INVALID; /* Ensure share name, pathname and comment don't contain '"' characters. */ string_replace(share_name, '"', ' '); - string_replace(ptr, '"', ' '); + string_replace(path, '"', ' '); string_replace(comment, '"', ' '); DEBUG(10,("_srv_net_share_set_info: change share command = %s\n", @@ -1562,12 +1567,12 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S /* Only call modify function if something changed. */ - if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) { + if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) { if (!lp_change_share_cmd() || !*lp_change_share_cmd()) return WERR_ACCESS_DENIED; slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"", - lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment); + lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment); DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command )); if ((ret = smbrun(command, NULL)) != 0) { @@ -1575,6 +1580,12 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S return WERR_ACCESS_DENIED; } + /* Check if the new share pathname exist, if not return an error */ + if (!exist_share_pathname(path)) { + DEBUG(1, ("_srv_net_share_set_info: change share command was ok but path (%s) has not been created!\n", path)); + return WERR_OBJECT_PATH_INVALID; + } + /* Tell everyone we updated smb.conf. */ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL); @@ -1615,7 +1626,7 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S int type; int snum; int ret; - char *ptr; + char *path; SEC_DESC *psd = NULL; DEBUG(5,("_srv_net_share_add: %d\n", __LINE__)); @@ -1689,16 +1700,16 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S return WERR_ACCESS_DENIED; /* Check if the pathname is valid. */ - if (!(ptr = valid_share_pathname( pathname ))) + if (!(path = valid_share_pathname( pathname ))) return WERR_OBJECT_PATH_INVALID; /* Ensure share name, pathname and comment don't contain '"' characters. */ string_replace(share_name, '"', ' '); - string_replace(ptr, '"', ' '); + string_replace(path, '"', ' '); string_replace(comment, '"', ' '); slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"", - lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment); + lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment); DEBUG(10,("_srv_net_share_add: Running [%s]\n", command )); if ((ret = smbrun(command, NULL)) != 0) { @@ -1706,10 +1717,33 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S return WERR_ACCESS_DENIED; } + /* Check if the new share pathname exist, if not try to delete the + * share and return an error */ + if (!exist_share_pathname(path)) { + DEBUG(1, ("_srv_net_share_add: add share command was ok but path (%s) has not been created!\n", path)); + DEBUG(1, ("_srv_net_share_add: trying to rollback and delete the share\n")); + + if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) { + DEBUG(1, ("_srv_net_share_add: Error! delete share command is not defined! Please check share (%s) in the config file\n", share_name)); + return WERR_OBJECT_PATH_INVALID; + } + + slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", + lp_delete_share_cmd(), dyn_CONFIGFILE, share_name); + + DEBUG(10,("_srv_net_share_add: Running [%s]\n", command )); + if ((ret = smbrun(command, NULL)) != 0) { + DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret )); + DEBUG(1, ("_srv_net_share_add: Error! delete share command failed! Please check share (%s) in the config file\n", share_name)); + } + + return WERR_OBJECT_PATH_INVALID; + } + if (psd) { - if (!set_share_security(p->mem_ctx, share_name, psd)) - DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", - share_name )); + if (!set_share_security(p->mem_ctx, share_name, psd)) { + DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name )); + } } /* Tell everyone we updated smb.conf. */ diff --git a/source3/sam/gums.c b/source3/sam/gums.c index 91009f8b5d..b719153584 100644 --- a/source3/sam/gums.c +++ b/source3/sam/gums.c @@ -26,71 +26,8 @@ #define GMV_MAJOR 0 #define GMV_MINOR 1 -#define PRIV_NONE 0 -#define PRIV_CREATE_TOKEN 1 -#define PRIV_ASSIGNPRIMARYTOKEN 2 -#define PRIV_LOCK_MEMORY 3 -#define PRIV_INCREASE_QUOTA 4 -#define PRIV_MACHINE_ACCOUNT 5 -#define PRIV_TCB 6 -#define PRIV_SECURITY 7 -#define PRIV_TAKE_OWNERSHIP 8 -#define PRIV_LOAD_DRIVER 9 -#define PRIV_SYSTEM_PROFILE 10 -#define PRIV_SYSTEMTIME 11 -#define PRIV_PROF_SINGLE_PROCESS 12 -#define PRIV_INC_BASE_PRIORITY 13 -#define PRIV_CREATE_PAGEFILE 14 -#define PRIV_CREATE_PERMANENT 15 -#define PRIV_BACKUP 16 -#define PRIV_RESTORE 17 -#define PRIV_SHUTDOWN 18 -#define PRIV_DEBUG 19 -#define PRIV_AUDIT 20 -#define PRIV_SYSTEM_ENVIRONMENT 21 -#define PRIV_CHANGE_NOTIFY 22 -#define PRIV_REMOTE_SHUTDOWN 23 -#define PRIV_UNDOCK 24 -#define PRIV_SYNC_AGENT 25 -#define PRIV_ENABLE_DELEGATION 26 -#define PRIV_ALL 255 - - static GUMS_FUNCTIONS *gums_backend = NULL; -#if 0 -static PRIVS gums_privs[] = { - {PRIV_NONE, "no_privs", "No privilege"}, /* this one MUST be first */ - {PRIV_CREATE_TOKEN, "SeCreateToken", "Create Token"}, - {PRIV_ASSIGNPRIMARYTOKEN, "SeAssignPrimaryToken", "Assign Primary Token"}, - {PRIV_LOCK_MEMORY, "SeLockMemory", "Lock Memory"}, - {PRIV_INCREASE_QUOTA, "SeIncreaseQuotaPrivilege", "Increase Quota Privilege"}, - {PRIV_MACHINE_ACCOUNT, "SeMachineAccount", "Machine Account"}, - {PRIV_TCB, "SeTCB", "TCB"}, - {PRIV_SECURITY, "SeSecurityPrivilege", "Security Privilege"}, - {PRIV_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege", "Take Ownership Privilege"}, - {PRIV_LOAD_DRIVER, "SeLocalDriverPrivilege", "Local Driver Privilege"}, - {PRIV_SYSTEM_PROFILE, "SeSystemProfilePrivilege", "System Profile Privilege"}, - {PRIV_SYSTEMTIME, "SeSystemtimePrivilege", "System Time"}, - {PRIV_PROF_SINGLE_PROCESS, "SeProfileSingleProcessPrivilege", "Profile Single Process Privilege"}, - {PRIV_INC_BASE_PRIORITY, "SeIncreaseBasePriorityPrivilege", "Increase Base Priority Privilege"}, - {PRIV_CREATE_PAGEFILE, "SeCreatePagefilePrivilege", "Create Pagefile Privilege"}, - {PRIV_CREATE_PERMANENT, "SeCreatePermanent", "Create Permanent"}, - {PRIV_BACKUP, "SeBackupPrivilege", "Backup Privilege"}, - {PRIV_RESTORE, "SeRestorePrivilege", "Restore Privilege"}, - {PRIV_SHUTDOWN, "SeShutdownPrivilege", "Shutdown Privilege"}, - {PRIV_DEBUG, "SeDebugPrivilege", "Debug Privilege"}, - {PRIV_AUDIT, "SeAudit", "Audit"}, - {PRIV_SYSTEM_ENVIRONMENT, "SeSystemEnvironmentPrivilege", "System Environment Privilege"}, - {PRIV_CHANGE_NOTIFY, "SeChangeNotify", "Change Notify"}, - {PRIV_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Remote Shutdown Privilege"}, - {PRIV_UNDOCK, "SeUndock", "Undock"}, - {PRIV_SYNC_AGENT, "SeSynchronizationAgent", "Synchronization Agent"}, - {PRIV_ENABLE_DELEGATION, "SeEnableDelegation", "Enable Delegation"}, - {PRIV_ALL, "SaAllPrivs", "All Privileges"} -}; -#endif - static struct gums_init_function_entry *backends = NULL; static void lazy_initialize_gums(void) diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index e3df8a11d0..8e4df1a464 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -991,7 +991,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw if (!push_sec_ctx()) return NT_STATUS_UNSUCCESSFUL; - set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL); + set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL, NULL); set_re_uid(); } diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 9bac0acdb9..0805f8e690 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -249,6 +249,14 @@ void conn_free(connection_struct *conn) conn->ngroups = 0; } + if (conn->nt_user_token) { + delete_nt_token(&(conn->nt_user_token)); + } + + if (conn->privs) { + destroy_privilege(&(conn->privs)); + } + free_namearray(conn->veto_list); free_namearray(conn->hide_list); free_namearray(conn->veto_oplock_list); diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 10c6aadb1f..8438f2a593 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -87,6 +87,7 @@ void invalidate_vuid(uint16 vuid) SAFE_FREE(vuser->groups); delete_nt_token(&vuser->nt_user_token); + destroy_privilege(&vuser->privs); SAFE_FREE(vuser); num_validated_vuids--; } @@ -234,6 +235,11 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, return UID_FIELD_INVALID; } + if (server_info->privs) { + init_privilege(&(vuser->privs)); + dup_priv_set(vuser->privs, server_info->privs); + } + /* use this to keep tabs on all our info from the authentication */ vuser->server_info = server_info; diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c index 8a85792ead..9244f34394 100644 --- a/source3/smbd/sec_ctx.c +++ b/source3/smbd/sec_ctx.c @@ -28,6 +28,7 @@ struct sec_ctx { int ngroups; gid_t *groups; NT_USER_TOKEN *token; + PRIVILEGE_SET *privs; }; /* A stack of security contexts. We include the current context as being @@ -256,6 +257,10 @@ BOOL push_sec_ctx(void) (unsigned int)ctx_p->uid, (unsigned int)ctx_p->gid, sec_ctx_stack_ndx )); ctx_p->token = dup_nt_token(sec_ctx_stack[sec_ctx_stack_ndx-1].token); + if (! ctx_p->token) { + DEBUG(0, ("Out of memory in push_sec_ctx()\n")); + return False; + } ctx_p->ngroups = sys_getgroups(0, NULL); @@ -271,6 +276,14 @@ BOOL push_sec_ctx(void) ctx_p->groups = NULL; } + init_privilege(&ctx_p->privs); + if (! NT_STATUS_IS_OK(dup_priv_set(ctx_p->privs, sec_ctx_stack[sec_ctx_stack_ndx-1].privs))) { + DEBUG(0, ("Out of memory in push_sec_ctx()\n")); + delete_nt_token(&ctx_p->token); + destroy_privilege(&ctx_p->privs); + return False; + } + return True; } @@ -278,7 +291,7 @@ BOOL push_sec_ctx(void) Set the current security context to a given user. ****************************************************************************/ -void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token) +void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token, PRIVILEGE_SET *privs) { struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx]; @@ -303,9 +316,14 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN smb_panic("DUPLICATE_TOKEN"); delete_nt_token(&ctx_p->token); + if (ctx_p->privs) + reset_privilege(ctx_p->privs); + else + init_privilege(&ctx_p->privs); ctx_p->groups = memdup(groups, sizeof(gid_t) * ngroups); ctx_p->token = dup_nt_token(token); + dup_priv_set(ctx_p->privs, privs); become_id(uid, gid); @@ -319,6 +337,7 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN current_user.ngroups = ngroups; current_user.groups = groups; current_user.nt_user_token = ctx_p->token; + current_user.privs = ctx_p->privs; } /**************************************************************************** @@ -329,7 +348,7 @@ void set_root_sec_ctx(void) { /* May need to worry about supplementary groups at some stage */ - set_sec_ctx(0, 0, 0, NULL, NULL); + set_sec_ctx(0, 0, 0, NULL, NULL, NULL); } /**************************************************************************** @@ -359,6 +378,7 @@ BOOL pop_sec_ctx(void) ctx_p->ngroups = 0; delete_nt_token(&ctx_p->token); + destroy_privilege(&ctx_p->privs); /* Pop back previous user */ @@ -381,6 +401,7 @@ BOOL pop_sec_ctx(void) current_user.ngroups = prev_ctx_p->ngroups; current_user.groups = prev_ctx_p->groups; current_user.nt_user_token = prev_ctx_p->token; + current_user.privs = prev_ctx_p->privs; DEBUG(3, ("pop_sec_ctx (%u, %u) - sec_ctx_stack_ndx = %d\n", (unsigned int)geteuid(), (unsigned int)getegid(), sec_ctx_stack_ndx)); @@ -413,6 +434,7 @@ void init_sec_ctx(void) get_current_groups(ctx_p->gid, &ctx_p->ngroups, &ctx_p->groups); ctx_p->token = NULL; /* Maps to guest user. */ + ctx_p->privs = NULL; /* Initialise current_user global */ @@ -427,4 +449,5 @@ void init_sec_ctx(void) current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; current_user.nt_user_token = NULL; + current_user.privs = NULL; } diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 78b610ae37..caa2872f04 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -371,6 +371,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, string_set(&conn->dirpath,""); string_set(&conn->user,user); conn->nt_user_token = NULL; + conn->privs = NULL; conn->read_only = lp_readonly(conn->service); conn->admin_user = False; @@ -479,6 +480,9 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, conn->nt_user_token = create_nt_token(conn->uid, conn->gid, conn->ngroups, conn->groups, guest); + + init_privilege(&(conn->privs)); + pdb_get_privilege_set(conn->nt_user_token, conn->privs); } /* diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 3859298055..d43bf301e8 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -44,7 +44,7 @@ BOOL change_to_guest(void) initgroups(pass->pw_name, pass->pw_gid); #endif - set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL); + set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL, NULL); current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; @@ -161,8 +161,9 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) gid_t gid; uid_t uid; char group_c; - BOOL must_free_token = False; + BOOL must_free_token_priv = False; NT_USER_TOKEN *token = NULL; + PRIVILEGE_SET *privs = NULL; if (!conn) { DEBUG(2,("change_to_user: Connection not open\n")); @@ -195,12 +196,14 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) current_user.groups = conn->groups; current_user.ngroups = conn->ngroups; token = conn->nt_user_token; + privs = conn->privs; } else if ((vuser) && check_user_ok(conn, vuser, snum)) { uid = conn->admin_user ? 0 : vuser->uid; gid = vuser->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; token = vuser->nt_user_token; + privs = vuser->privs; } else { DEBUG(2,("change_to_user: Invalid vuid used %d or vuid not permitted access to share.\n",vuid)); return False; @@ -248,17 +251,20 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) DEBUG(1, ("change_to_user: create_nt_token failed!\n")); return False; } - must_free_token = True; + pdb_get_privilege_set(token, privs); + must_free_token_priv = True; } - set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token); + set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token, privs); /* * Free the new token (as set_sec_ctx copies it). */ - if (must_free_token) + if (must_free_token_priv) { delete_nt_token(&token); + destroy_privilege(&privs); + } current_user.conn = conn; current_user.vuid = vuid; @@ -299,7 +305,7 @@ BOOL become_authenticated_pipe_user(pipes_struct *p) return False; set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token); + p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token, p->pipe_user.privs); return True; } diff --git a/source3/utils/net.c b/source3/utils/net.c index 8004ced43e..fcc8b4abe1 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -648,6 +648,7 @@ static struct functable net_func[] = { #ifdef WITH_FAKE_KASERVER {"AFSKEY", net_afskey}, #endif + {"PRIV", net_priv}, {"HELP", net_help}, {NULL, NULL} -- cgit From fcab2e5cfb524afa327fbafa2915c73527f14ea6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 1 Mar 2004 17:03:23 +0000 Subject: BUG 1147; bad pointer case in get_stored_queue_info() causing seg fault (This used to be commit eb8a8c290f893b6ffa3d16e282829230be56b212) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1f0bb1e074..c453eb796c 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2183,7 +2183,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun uint32 jobid; struct printjob *pjob; - jobid = IVAL(&cgdata.dptr, i*4); + jobid = IVAL(cgdata.dptr, i*4); DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid)); pjob = print_job_find(snum, jobid); if (!pjob) { -- cgit From 52be5d83191a46151511531824d1d12c1615808d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 2 Mar 2004 04:19:47 +0000 Subject: merging from 3.0 (This used to be commit fae17e0f9d228bab9992287507babd6a8fd53f97) --- source3/client/client.c | 8 ++-- source3/param/loadparm.c | 96 +++++++++++++++++++++++++----------------------- 2 files changed, 54 insertions(+), 50 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index d4ad5fa1fe..547ebe8029 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2003,7 +2003,7 @@ static void browse_fn(const char *name, uint32 m, in any of these fields, they can corrupt the output. We should remove them. */ if (!grepable) { - d_printf("\t%-15.15s%-10.10s%s\n", + d_printf("\t%-15s %-10.10s%s\n", name,typestr,comment); } else { d_printf ("%s|%s|%s\n",typestr,name,comment); @@ -2018,8 +2018,8 @@ static BOOL browse_host(BOOL sort) { int ret; if (!grepable) { - d_printf("\n\tSharename Type Comment\n"); - d_printf("\t--------- ---- -------\n"); + d_printf("\n\tSharename Type Comment\n"); + d_printf("\t--------- ---- -------\n"); } if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1) @@ -2037,7 +2037,7 @@ static void server_fn(const char *name, uint32 m, { if (!grepable){ - d_printf("\t%-16.16s %s\n", name, comment); + d_printf("\t%-16s %s\n", name, comment); } else { d_printf("%s|%s|%s\n",(char *)state, name, comment); } diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 58f4919465..a72f7f878b 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -1176,61 +1176,66 @@ static struct parm_struct parm_table[] = { Initialise the sDefault parameter structure for the printer values. ***************************************************************************/ -static void init_printer_values(void) +static void init_printer_values(service *pService) { + if ( pService == NULL ) { + DEBUG(0,("init_printer_values: NULL pointer\n")); + return; + } + /* choose defaults depending on the type of printing */ - switch (sDefault.iPrinting) { + switch (pService->iPrinting) { case PRINT_BSD: case PRINT_AIX: case PRINT_LPRNT: case PRINT_LPROS2: - string_set(&sDefault.szLpqcommand, "lpq -P'%p'"); - string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j"); - string_set(&sDefault.szPrintcommand, + string_set(&pService->szLpqcommand, "lpq -P'%p'"); + string_set(&pService->szLprmcommand, "lprm -P'%p' %j"); + string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s"); break; case PRINT_LPRNG: case PRINT_PLP: - string_set(&sDefault.szLpqcommand, "lpq -P'%p'"); - string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j"); - string_set(&sDefault.szPrintcommand, + string_set(&pService->szLpqcommand, "lpq -P'%p'"); + string_set(&pService->szLprmcommand, "lprm -P'%p' %j"); + string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s"); - string_set(&sDefault.szQueuepausecommand, + string_set(&pService->szQueuepausecommand, "lpc stop '%p'"); - string_set(&sDefault.szQueueresumecommand, + string_set(&pService->szQueueresumecommand, "lpc start '%p'"); - string_set(&sDefault.szLppausecommand, + string_set(&pService->szLppausecommand, "lpc hold '%p' %j"); - string_set(&sDefault.szLpresumecommand, + string_set(&pService->szLpresumecommand, "lpc release '%p' %j"); break; case PRINT_CUPS: #ifdef HAVE_CUPS - string_set(&sDefault.szLpqcommand, ""); - string_set(&sDefault.szLprmcommand, ""); - string_set(&sDefault.szPrintcommand, ""); - string_set(&sDefault.szLppausecommand, ""); - string_set(&sDefault.szLpresumecommand, ""); - string_set(&sDefault.szQueuepausecommand, ""); - string_set(&sDefault.szQueueresumecommand, ""); + string_set(&pService->szLpqcommand, ""); + string_set(&pService->szLprmcommand, ""); + string_set(&pService->szPrintcommand, ""); + string_set(&pService->szLppausecommand, ""); + string_set(&pService->szLpresumecommand, ""); + string_set(&pService->szQueuepausecommand, ""); + string_set(&pService->szQueueresumecommand, ""); string_set(&Globals.szPrintcapname, "cups"); #else - string_set(&sDefault.szLpqcommand, + string_set(&pService->szLpqcommand, "/usr/bin/lpstat -o '%p'"); - string_set(&sDefault.szLprmcommand, + string_set(&pService->szLprmcommand, "/usr/bin/cancel '%p-%j'"); - string_set(&sDefault.szPrintcommand, + string_set(&pService->szPrintcommand, "/usr/bin/lp -d '%p' %s; rm %s"); - string_set(&sDefault.szLppausecommand, + string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold"); - string_set(&sDefault.szLpresumecommand, + string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume"); - string_set(&sDefault.szQueuepausecommand, + string_set(&pService->szQueuepausecommand, "/usr/bin/disable '%p'"); - string_set(&sDefault.szQueueresumecommand, + string_set(&pService->szQueueresumecommand, "/usr/bin/enable '%p'"); string_set(&Globals.szPrintcapname, "lpstat"); #endif /* HAVE_CUPS */ @@ -1238,38 +1243,38 @@ static void init_printer_values(void) case PRINT_SYSV: case PRINT_HPUX: - string_set(&sDefault.szLpqcommand, "lpstat -o%p"); - string_set(&sDefault.szLprmcommand, "cancel %p-%j"); - string_set(&sDefault.szPrintcommand, + string_set(&pService->szLpqcommand, "lpstat -o%p"); + string_set(&pService->szLprmcommand, "cancel %p-%j"); + string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s"); - string_set(&sDefault.szQueuepausecommand, + string_set(&pService->szQueuepausecommand, "disable %p"); - string_set(&sDefault.szQueueresumecommand, + string_set(&pService->szQueueresumecommand, "enable %p"); #ifndef HPUX - string_set(&sDefault.szLppausecommand, + string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold"); - string_set(&sDefault.szLpresumecommand, + string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume"); #endif /* HPUX */ break; case PRINT_QNX: - string_set(&sDefault.szLpqcommand, "lpq -P%p"); - string_set(&sDefault.szLprmcommand, "lprm -P%p %j"); - string_set(&sDefault.szPrintcommand, "lp -r -P%p %s"); + string_set(&pService->szLpqcommand, "lpq -P%p"); + string_set(&pService->szLprmcommand, "lprm -P%p %j"); + string_set(&pService->szPrintcommand, "lp -r -P%p %s"); break; #ifdef DEVELOPER case PRINT_TEST: case PRINT_VLP: - string_set(&sDefault.szPrintcommand, "vlp print %p %s"); - string_set(&sDefault.szLpqcommand, "vlp lpq %p"); - string_set(&sDefault.szLprmcommand, "vlp lprm %p %j"); - string_set(&sDefault.szLppausecommand, "vlp lppause %p %j"); - string_set(&sDefault.szLpresumecommand, "vlp lpresum %p %j"); - string_set(&sDefault.szQueuepausecommand, "vlp queuepause %p"); - string_set(&sDefault.szQueueresumecommand, "vlp queueresume %p"); + string_set(&pService->szPrintcommand, "vlp print %p %s"); + string_set(&pService->szLpqcommand, "vlp lpq %p"); + string_set(&pService->szLprmcommand, "vlp lprm %p %j"); + string_set(&pService->szLppausecommand, "vlp lppause %p %j"); + string_set(&pService->szLpresumecommand, "vlp lpresum %p %j"); + string_set(&pService->szQueuepausecommand, "vlp queuepause %p"); + string_set(&pService->szQueueresumecommand, "vlp queueresume %p"); break; #endif /* DEVELOPER */ @@ -1297,8 +1302,6 @@ static void init_globals(void) string_set(&sDefault.fstype, FSTYPE_STRING); - init_printer_values(); - done_init = True; } @@ -2396,7 +2399,7 @@ BOOL lp_add_printer(const char *pszPrintername, int iDefaultService) ServicePtrs[i]->bOpLocks = False; /* Printer services must be printable. */ ServicePtrs[i]->bPrint_ok = True; - + DEBUG(3, ("adding printer service %s\n", pszPrintername)); return (True); @@ -3884,6 +3887,7 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults, } init_iconv(); + init_printer_values(&sDefault); return (bRetval); } -- cgit From a1169a863b0d3a576db59196c8fc3cf9eb66b0ff Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 2 Mar 2004 07:47:39 +0000 Subject: Expand aliases for winbind-generated groups. Do: wbinfo -C alias net groupmap set alias alias -L net rpc group addmem alias DOMAIN\\group -S localhost -Uroot%secret getent group alias And hopefully the members of domain\\group show up :-) Still have to get them to show up in 'getent group'. Volker (This used to be commit 18e48190838907a29347d471e81945257f540aa7) --- source3/nsswitch/winbindd_acct.c | 154 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/source3/nsswitch/winbindd_acct.c b/source3/nsswitch/winbindd_acct.c index 0d96756fdb..e8d647614b 100644 --- a/source3/nsswitch/winbindd_acct.c +++ b/source3/nsswitch/winbindd_acct.c @@ -174,6 +174,158 @@ static char* passwd2string( const WINBINDD_PW *pw ) return string; } +static void +add_member(const char *domain, const char *user, + char ***members, int *num_members) +{ + fstring name; + + fill_domain_username(name, domain, user); + + *members = Realloc(*members, (*num_members+1) * sizeof(char **)); + + if (members == NULL) { + DEBUG(10, ("Realloc failed\n")); + return; + } + + (*members)[*num_members] = strdup(name); + *num_members += 1; +} + +/********************************************************************** + Add member users resulting from sid. Expand if it is a domain group. +**********************************************************************/ + +static void +add_expanded_sid(DOM_SID *sid, char ***members, int *num_members) +{ + DOM_SID dom_sid; + uint32 rid; + struct winbindd_domain *domain; + int i; + + char *name = NULL; + enum SID_NAME_USE type; + + uint32 num_names; + DOM_SID **sid_mem; + char **names; + uint32 *types; + + NTSTATUS result; + + TALLOC_CTX *mem_ctx = talloc_init("add_expanded_sid"); + + if (mem_ctx == NULL) { + DEBUG(1, ("talloc_init failed\n")); + return; + } + + sid_copy(&dom_sid, sid); + sid_split_rid(&dom_sid, &rid); + + domain = find_domain_from_sid(&dom_sid); + + if (domain == NULL) { + DEBUG(3, ("Could not find domain for sid %s\n", + sid_string_static(sid))); + goto done; + } + + result = domain->methods->sid_to_name(domain, mem_ctx, sid, + &name, &type); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3, ("sid_to_name failed for sid %s\n", + sid_string_static(sid))); + goto done; + } + + DEBUG(10, ("Found name %s, type %d\n", name, type)); + + if (type == SID_NAME_USER) { + add_member(domain->name, name, members, num_members); + goto done; + } + + if (type != SID_NAME_DOM_GRP) { + DEBUG(10, ("Alias member %s neither user nor group, ignore\n", + name)); + goto done; + } + + /* Expand the domain group */ + + result = domain->methods->lookup_groupmem(domain, mem_ctx, + sid, &num_names, + &sid_mem, &names, + &types); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10, ("Could not lookup group members for %s: %s\n", + name, nt_errstr(result))); + goto done; + } + + for (i=0; iname, names[i], members, num_members); + } + + done: + talloc_destroy(mem_ctx); + return; +} + +/********************************************************************** + Add alias members. Expand them if they are domain groups. +**********************************************************************/ + +static void +add_expanded_alias_members(gid_t gid, char ***members, int *num_members) +{ + GROUP_MAP map; + DOM_SID *sids = NULL; + int i, num_sids; + + if (!pdb_getgrgid(&map, gid)) { + DEBUG(10, ("No mapping for group %d\n", gid)); + return; + } + + if ( (map.sid_name_use != SID_NAME_WKN_GRP) && + (map.sid_name_use != SID_NAME_ALIAS) ) { + DEBUG(10, ("Group %d is no alias\n", gid)); + return; + } + + if (!pdb_enum_aliasmem(&map.sid, &sids, &num_sids)) { + DEBUG(10, ("Could not enum aliases for group sid %s\n", + sid_string_static(&map.sid))); + return; + } + + for (i=0; i Date: Tue, 2 Mar 2004 10:09:52 +0000 Subject: Sorry, forgot to commit an essential piece. (This used to be commit fa6500fe773ae1f0aa70f370600b6f7aa7f65f3d) --- source3/utils/net_privileges.c | 363 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 source3/utils/net_privileges.c diff --git a/source3/utils/net_privileges.c b/source3/utils/net_privileges.c new file mode 100644 index 0000000000..2e8bfe0c83 --- /dev/null +++ b/source3/utils/net_privileges.c @@ -0,0 +1,363 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-2000, + * Copyright (C) Jean François Micouleau 1998-2001. + * Copyright (C) Gerald Carter 2003. + * Copyright (C) Simo Sorce 2003. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "includes.h" +#include "../utils/net.h" + +extern PRIVS privs[]; + +/********************************************************* + utility function to parse an integer parameter from + "parameter = value" +**********************************************************/ +static uint32 get_int_param( const char* param ) +{ + char *p; + + p = strchr( param, '=' ); + if ( !p ) + return 0; + + return atoi(p+1); +} + +/********************************************************* + utility function to parse an integer parameter from + "parameter = value" +**********************************************************/ +static char* get_string_param( const char* param ) +{ + char *p; + + p = strchr( param, '=' ); + if ( !p ) + return NULL; + + return (p+1); +} + +/********************************************************* + Dump a GROUP_MAP entry to stdout (long or short listing) +**********************************************************/ + +static void print_priv_entry(const char *privname, const char *description, const char *sid_list) +{ + + if (!sid_list) { + d_printf("Error getting privilege list!\n"); + return; + } + + if (!description) + d_printf("%s\n", privname); + else { + d_printf("%s\n", privname); + d_printf("\tdescription: %s\n", description); + d_printf("\tSIDS: %s\n", sid_list); + } +} + +/********************************************************* + List the groups. +**********************************************************/ +static int net_priv_list(int argc, const char **argv) +{ + BOOL long_list = False; + fstring privname = ""; + fstring sid_string = ""; + int i; + + /* get the options */ + for ( i=0; i|sid=} privilege=\n"); + return -1; + } + + if ((rid == 0) && (sid_string[0] == '\0')) { + d_printf("No rid or sid specified\n"); + d_printf("Usage: net print add {rid=|sid=} privilege=\n"); + return -1; + } + + /* append the rid to our own domain/machine SID if we don't have a full SID */ + if (!sid_string[0]) { + sid_copy(&sid, get_global_sam_sid()); + sid_append_rid(&sid, rid); + sid_to_string(sid_string, &sid); + } + + if (!pdb_add_sid_to_privilege(privname, &sid)) { + d_printf("adding sid %s to privilege %s failed!\n", sid_string, privname); + return -1; + } + + d_printf("Successully added SID %s to privilege %s\n", sid_string, privname); + return 0; +} + +/********************************************************* + Remove a SID froma privilege entry +**********************************************************/ + +static int net_priv_remove(int argc, const char **argv) +{ + DOM_SID sid; + fstring privname = ""; + fstring sid_string = ""; + uint32 rid = 0; + int i; + + /* get the options */ + for ( i=0; i|sid=} privilege=\n"); + return -1; + } + + if ((rid == 0) && (sid_string[0] == '\0')) { + d_printf("No rid or sid specified\n"); + d_printf("Usage: net print add {rid=|sid=} privilege=\n"); + return -1; + } + + /* append the rid to our own domain/machine SID if we don't have a full SID */ + if (!sid_string[0]) { + sid_copy(&sid, get_global_sam_sid()); + sid_append_rid(&sid, rid); + sid_to_string(sid_string, &sid); + } + + if (!pdb_remove_sid_from_privilege(privname, &sid)) { + d_printf("adding sid %s to privilege %s failed!\n", sid_string, privname); + return -1; + } + + d_printf("Successully removed SID %s from privilege %s\n", sid_string, privname); + return 0; +} + +int net_help_priv(int argc, const char **argv) +{ + d_printf("net priv add sid\n" \ + " Add sid to privilege\n"); + d_printf("net priv remove sid\n"\ + " Remove sid from privilege\n"); + d_printf("net priv list\n"\ + " List sids per privilege\n"); + + return -1; +} + + +/*********************************************************** + migrated functionality from smbgroupedit + **********************************************************/ +int net_priv(int argc, const char **argv) +{ + struct functable func[] = { + {"add", net_priv_add}, + {"remove", net_priv_remove}, + {"list", net_priv_list}, + {"help", net_help_priv}, + {NULL, NULL} + }; + + /* we shouldn't have silly checks like this */ + if (getuid() != 0) { + d_printf("You must be root to edit privilege mappings.\nExiting...\n"); + return -1; + } + + if ( argc ) + return net_run_function(argc, argv, func, net_help_priv); + + return net_help_priv(argc, argv); +} + -- cgit From 4faa480a4a5662b73012680d3f3f2284fdc7af60 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 2 Mar 2004 14:19:44 +0000 Subject: Idra, your privileges patch allowed login only with tdbsam. The problem is that pdb_default_get_privilege_set returns NOT_IMPLEMENTED and not a privilege set that does not grant anything. I don't really understand privileges yet, so work around that by not failing if pdb_get_privilege_set fails. Volker (This used to be commit b790753f443092a65eeef7b146a18d4c5ffcb323) --- source3/auth/auth_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 018d3b1851..871b399b86 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -836,7 +836,7 @@ static NTSTATUS add_privileges(auth_serversupplied_info **server_info) init_privilege(&privs); if (!pdb_get_privilege_set((*server_info)->ptok, privs)) - return NT_STATUS_UNSUCCESSFUL; + DEBUG(1, ("Could not add privileges\n")); (*server_info)->privs = privs; -- cgit From 923a0bed5c6062e620ed3d4ba57c01e6eb86b5b6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 2 Mar 2004 14:29:01 +0000 Subject: allow the 'printing' parameter to be set on a per share basis. The problem was that the current_printif struct was set during print_backend_init() based on the 'printcap name'. So you could not use cups and then override the setting for a specific printer by setting 'printing = bsd' (a common setup for pdf generation print services. There is a subtle change in behavior in that the print interface functions are selecting on the basis of lp_printing() and not lp_printcap_name(), but the new behavior seems more intuitive IMHO. (This used to be commit e721255e8f7d719dbcc2cad94c9b11f6124676e6) --- source3/printing/printing.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c453eb796c..1efd932749 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -24,7 +24,6 @@ #include "printing.h" /* Current printer interface */ -static struct printif *current_printif = &generic_printif; static BOOL remove_from_jobs_changed(int snum, uint32 jobid); /* @@ -206,12 +205,6 @@ BOOL print_backend_init(void) close_all_print_db(); /* Don't leave any open. */ - /* select the appropriate printing interface... */ -#ifdef HAVE_CUPS - if (strcmp(lp_printcapname(), "cups") == 0) - current_printif = &cups_printif; -#endif /* HAVE_CUPS */ - /* do NT print initialization... */ return nt_printing_init(); } @@ -225,6 +218,28 @@ void printing_end(void) close_all_print_db(); /* Don't leave any open. */ } +/**************************************************************************** + Retrieve the set of printing functions for a given service. This allows + us to set the printer function table based on the value of the 'printing' + service parameter. + + Use the generic interface as the default and only use cups interface only + when asked for (and only when supported) +****************************************************************************/ + +static struct printif *get_printer_fns( int snum ) +{ + struct printif *printer_fns = &generic_printif; + +#ifdef HAVE_CUPS + if ( lp_printing(snum) == PRINT_CUPS ) { + printer_fns = &cups_printif; + } +#endif /* HAVE_CUPS */ + + return printer_fns; +} + /**************************************************************************** Useful function to generate a tdb key. ****************************************************************************/ @@ -951,6 +966,7 @@ static void print_queue_update(int snum) TDB_DATA data, key; TDB_DATA jcdata; struct tdb_print_db *pdb; + struct printif *current_printif = get_printer_fns( snum ); fstrcpy(printer_name, lp_const_servicename(snum)); pdb = get_print_db_byname(printer_name); @@ -1448,6 +1464,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid) { struct printjob *pjob = print_job_find(snum, jobid); int result = 0; + struct printif *current_printif = get_printer_fns( snum ); if (!pjob) return False; @@ -1589,6 +1606,7 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR * { struct printjob *pjob = print_job_find(snum, jobid); int ret = -1; + struct printif *current_printif = get_printer_fns( snum ); if (!pjob || !user) return False; @@ -1639,6 +1657,7 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR { struct printjob *pjob = print_job_find(snum, jobid); int ret; + struct printif *current_printif = get_printer_fns( snum ); if (!pjob || !user) return False; @@ -2040,6 +2059,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) struct printjob *pjob = print_job_find(snum, jobid); int ret; SMB_STRUCT_STAT sbuf; + struct printif *current_printif = get_printer_fns( snum ); if (!pjob) return False; @@ -2296,6 +2316,7 @@ int print_queue_status(int snum, BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) { int ret; + struct printif *current_printif = get_printer_fns( snum ); if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { *errcode = WERR_ACCESS_DENIED; @@ -2326,6 +2347,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode) BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode) { int ret; + struct printif *current_printif = get_printer_fns( snum ); if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { *errcode = WERR_ACCESS_DENIED; -- cgit From b5c98c295c1131e805cccbbfbf061cf723b221c3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 2 Mar 2004 14:49:06 +0000 Subject: This adds winbind-generated groups showing up in 'getent group'. It is not very efficient though, it only does one group at a time. Needs improving, but the structures are not particularly easy to set up, so check in the basically working part for others to review. I'm close to saying that I would like to remove aliases from general group mapping. These can not be reflected correctly in /etc/group, winbind could do a better job here. And having aliases only on machines with nss_winbind at least for me is not a too severe limitation. Comments? Volker (This used to be commit 6cad5bcc280c2964473346cc467423a44cc6a5c2) --- source3/nsswitch/winbindd.h | 5 +++ source3/nsswitch/winbindd_acct.c | 50 +++++++++++++++++++++++ source3/nsswitch/winbindd_group.c | 86 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+) diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 7c8e6256e1..340ea07733 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -48,6 +48,11 @@ struct winbindd_cli_state { struct winbindd_response response; /* Respose to client */ struct getent_state *getpwent_state; /* State for getpwent() */ struct getent_state *getgrent_state; /* State for getgrent() */ + + /* Local groups for getgrent() */ + char **local_group_names; + int num_local_group_names; + int local_group_ndx; }; /* State between get{pw,gr}ent() calls */ diff --git a/source3/nsswitch/winbindd_acct.c b/source3/nsswitch/winbindd_acct.c index e8d647614b..28434496ce 100644 --- a/source3/nsswitch/winbindd_acct.c +++ b/source3/nsswitch/winbindd_acct.c @@ -1356,5 +1356,55 @@ enum winbindd_result winbindd_delete_group(struct winbindd_cli_state *state) return ( ret ? WINBINDD_OK : WINBINDD_ERROR ); } +static void add_string_to_array(char *name, char ***names, int *num_names) +{ + *names = Realloc(*names, (*num_names + 1) * sizeof(char **)); + + if (*names == NULL) + return; + + (*names)[*num_names] = name; + *num_names += 1; +} + +/********************************************************************** + List all group names locally defined +**********************************************************************/ + +void wb_list_group_names(char ***names, int *num_names) +{ + TDB_LIST_NODE *nodes, *node; + + if (!winbindd_accountdb_init()) + return; + nodes = tdb_search_keys(account_tdb, acct_groupkey_byname("*")); + node = nodes; + + while (node != NULL) { + char *name = (char *)node->node_key.dptr; + + DEBUG(10, ("Found key %s\n", name)); + + node = node->next; + + /* Skip WBA_GROUP */ + name = strchr(name, '/'); + if (name == NULL) + continue; + name += 1; + + /* Skip NAME */ + name = strchr(name, '/'); + if (name == NULL) + continue; + name += 1; + + DEBUG(10, ("adding %s\n", name)); + + add_string_to_array(strdup(name), names, num_names); + } + + tdb_search_list_free(nodes); +} diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 90597d9b3f..d09b4ec6f9 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -423,6 +423,15 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) free_getent_state(state->getgrent_state); state->getgrent_state = NULL; } + + /* Add our locally defined groups */ + + state->local_group_names = NULL; + state->num_local_group_names = 0; + state->local_group_ndx = 0; + + wb_list_group_names(&state->local_group_names, + &state->num_local_group_names); /* Create sam pipes for each domain we know about */ @@ -471,6 +480,80 @@ enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state) return WINBINDD_OK; } +/* Fetch group entries from local faked database */ + +static BOOL return_local_winbind_groups(struct winbindd_cli_state *state) +{ + WINBINDD_GR *grp; + char *buffer = NULL; + char *name; + int gr_mem_list_len = 0; + struct winbindd_gr *group_list; + struct winbindd_gr *gr; + + if (state->local_group_names == NULL) + return False; + + name = state->local_group_names[state->local_group_ndx]; + grp = wb_getgrnam(name); + + if (grp == NULL) { + DEBUG(3, ("Group %s vanished\n", name)); + + /* Stop that stuff.. */ + state->local_group_ndx = state->num_local_group_names; + + return False; + } + + gr_mem_list_len = gr_mem_buffer( &buffer, grp->gr_mem, grp->num_gr_mem ); + + state->response.extra_data = malloc(sizeof(struct winbindd_gr) + + gr_mem_list_len); + state->response.length += sizeof(struct winbindd_gr) + gr_mem_list_len; + + group_list = (struct winbindd_gr *)state->response.extra_data; + + if (group_list == NULL) { + DEBUG(0, ("Could not malloc group_list\n")); + return False; + } + + gr = &group_list[0]; + + ZERO_STRUCTP(gr); + + gr->gr_gid = grp->gr_gid; + safe_strcpy(gr->gr_name, name, sizeof(gr->gr_name) - 1); + safe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1); + gr->num_gr_mem = grp->num_gr_mem; + gr->gr_mem_ofs = 0; + + memcpy(&((char *)state->response.extra_data) + [sizeof(struct winbindd_gr)], + buffer, gr_mem_list_len); + + SAFE_FREE(buffer); + SAFE_FREE(grp->gr_mem); + + state->response.data.num_entries = 1; + + state->local_group_ndx += 1; + + if (state->local_group_ndx >= state->num_local_group_names) { + int i; + + for (i=0; inum_local_group_names; i++) { + free(state->local_group_names[i]); + } + free(state->local_group_names); + state->local_group_names = NULL; + } + + return True; +} + + /* Get the list of domain groups and domain aliases for a domain. We fill in the sam_entries and num_sam_entries fields with domain group information. The dispinfo_ndx field is incremented to the index of the next group to @@ -606,6 +689,9 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) if (!lp_winbind_enum_groups()) return WINBINDD_ERROR; + if (return_local_winbind_groups(state)) + return WINBINDD_OK; + num_groups = MIN(MAX_GETGRENT_GROUPS, state->request.data.num_entries); if ((state->response.extra_data = -- cgit From 6159be06a3b7af3d3a2502aca17c94ebebddac93 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 2 Mar 2004 15:34:46 +0000 Subject: Let's be polite with poorer backends ;-) (This used to be commit 90640a523e9898157a361f3fbf5923b1ef2a6651) --- source3/passdb/pdb_interface.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 180db58c2d..8307919d10 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1299,7 +1299,9 @@ static NTSTATUS pdb_default_remove_sid_from_privilege(struct pdb_methods *method static NTSTATUS pdb_default_get_privilege_set(struct pdb_methods *methods, NT_USER_TOKEN *token, PRIVILEGE_SET *privset) { - return NT_STATUS_NOT_IMPLEMENTED; + /* by default return the empty privilege set as otherwise login will + * be denied if a backend does not support privilege sets */ + return NT_STATUS_OK; } static NTSTATUS pdb_default_get_privilege_entry(struct pdb_methods *methods, const char *privname, char **sid_list) -- cgit From 5d123b0d92c48b2c40ffc969114d15d3dcd1fd11 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 2 Mar 2004 18:04:21 +0000 Subject: fix typo for callback bit (This used to be commit c1b1a1961f19e2fba680d48e41d0b29cdfd6d39c) --- source3/include/passdb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/include/passdb.h b/source3/include/passdb.h index d471eb53f3..65e342080e 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -51,7 +51,7 @@ #define ACCT_LAST_PWD_CHANGE 0x00040000 #define ACCT_EXPIRY 0x00080000 #define ACCT_FLAGS 0x00100000 -#define ACCT_CALLBACK 0x00200001 +#define ACCT_CALLBACK 0x00200000 #define ACCT_COUNTRY_CODE 0x00400000 #define ACCT_CODE_PAGE 0x00800000 #define ACCT_NT_PWD_SET 0x01000000 -- cgit From 32581b5d7b9f02af67ac020e7938b7ede316b027 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 2 Mar 2004 18:10:53 +0000 Subject: BUG 1129: patch from shiro@miraclelinux.com (Shiro Yamada) to install image files for SWAT (This used to be commit 42d8455a02fa89d37864d32c49d598ba9cdc1552) --- source3/script/installswat.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source3/script/installswat.sh b/source3/script/installswat.sh index c0285bda55..495386e0b7 100755 --- a/source3/script/installswat.sh +++ b/source3/script/installswat.sh @@ -81,6 +81,22 @@ if [ -d $SRCDIR../docs/htmldocs/ ]; then cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges? chmod 0644 $FNAME done + + if [ -d $SRCDIR../docs/htmldocs/images/ ]; then + if [ ! -d $SWATDIR/help/images/ ]; then + mkdir $SWATDIR/help/images + if [ ! -d $SWATDIR/help/images/ ]; then + echo Failed to make directory $SWATDIR/help/images, does $USER have privileges? + exit 1 + fi + fi + for f in $SRCDIR../docs/htmldocs/images/*.png; do + FNAME=$SWATDIR/help/images/`basename $f` + echo $FNAME + cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges? + chmod 0644 $FNAME + done + fi fi # Install Using Samba book (but only if it is there) -- cgit From 3bdcd5c8ce8ef9cc270e6dcf39ccf81484577bcd Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 3 Mar 2004 04:23:48 +0000 Subject: quick for for usrmgr. unknown_6 is really max dimension of logon hours array. need to update passdb for this. (This used to be commit 1d3079bf4c661939e291cca5e96157b5fa492340) --- source3/rpc_server/srv_samr_util.c | 42 +++++++++++--------------------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index 706c893c92..ae0fe84e02 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -256,6 +256,12 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) DEBUG(15,("INFO_21 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours)); /* Fix me: only update if it changes --metze */ pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED); + + /* This is max logon hours */ + DEBUG(10,("INFO_21 UNKNOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6)); + if (from->unknown_6 != pdb_get_unknown_6(to)) { + pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED); + } } if (from->fields_present & ACCT_BAD_PWD_COUNT) { @@ -272,21 +278,6 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) } } - /* if (from->fields_present & ACCT_??) { */ - DEBUG(10,("INFO_21 UNKNOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6)); - if (from->unknown_6 != pdb_get_unknown_6(to)) { - pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED); - } - /* } */ - - DEBUG(10,("INFO_21 PADDING1 %02X %02X %02X %02X %02X %02X\n", - from->padding1[0], - from->padding1[1], - from->padding1[2], - from->padding1[3], - from->padding1[4], - from->padding1[5])); - DEBUG(10,("INFO_21 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange)); if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) { pdb_set_pass_must_change_time(to,0, PDB_CHANGED); @@ -512,6 +503,12 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) DEBUG(15,("INFO_23 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours)); /* Fix me: only update if it changes --metze */ pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED); + + /* This is max logon hours */ + DEBUG(10,("INFO_23 UNKOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6)); + if (from->unknown_6 != pdb_get_unknown_6(to)) { + pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED); + } } if (from->fields_present & ACCT_BAD_PWD_COUNT) { @@ -528,21 +525,6 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) } } - /* if (from->fields_present & ACCT_??) { */ - DEBUG(10,("INFO_23 UNKOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6)); - if (from->unknown_6 != pdb_get_unknown_6(to)) { - pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED); - } - /* } */ - - DEBUG(10,("INFO_23 PADDING1 %02X %02X %02X %02X %02X %02X\n", - from->padding1[0], - from->padding1[1], - from->padding1[2], - from->padding1[3], - from->padding1[4], - from->padding1[5])); - DEBUG(10,("INFO_23 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange)); if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) { pdb_set_pass_must_change_time(to,0, PDB_CHANGED); -- cgit From 0dd6ea2f3a18290283a62888c9fa702aa343eed2 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 3 Mar 2004 17:44:10 +0000 Subject: more usrmgr fixes: display lockout timers in minutes, not seconds, for samr 2e (This used to be commit 95e7cfdb19bab4a5aac59e10afb3b1416e6079c5) --- source3/rpc_server/srv_samr_nt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 1959674f0a..15a4cf1ae4 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -4469,10 +4469,10 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW break; case 0x0c: account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp); - u_lock_duration = account_policy_temp; + u_lock_duration = account_policy_temp * 60; account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp); - u_reset_time = account_policy_temp; + u_reset_time = account_policy_temp * 60; account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp); lockout = account_policy_temp; -- cgit From 74307e350635a195ebaa4841651f555c27fbcff4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Mar 2004 20:55:40 +0000 Subject: Use a common function to parse all pathnames from the wire. This allows much closer emulation of Win2k3 error return codes. Jeremy. (This used to be commit 883f89a0184e37bff4f5877a25d31b994996ab08) --- source3/client/client.c | 46 +++++++- source3/include/smb.h | 6 + source3/include/smb_macros.h | 1 + source3/libsmb/clifile.c | 38 +++++++ source3/printing/nt_printing.c | 10 +- source3/smbd/filename.c | 27 ++--- source3/smbd/nttrans.c | 69 ++++++----- source3/smbd/reply.c | 253 ++++++++++++++++++++++++++++++----------- source3/smbd/trans2.c | 69 ++++++++--- 9 files changed, 383 insertions(+), 136 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 547ebe8029..d0bc01655f 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -577,9 +577,13 @@ static int cmd_dir(void) int rc; dir_total = 0; - pstrcpy(mask,cur_dir); - if(mask[strlen(mask)-1]!='\\') - pstrcat(mask,"\\"); + if (strcmp(cur_dir, "\\") != 0) { + pstrcpy(mask,cur_dir); + if(mask[strlen(mask)-1]!='\\') + pstrcat(mask,"\\"); + } else { + *mask = '\0'; + } if (next_token_nr(NULL,buf,NULL,sizeof(buf))) { dos_format(p); @@ -1769,6 +1773,38 @@ static int cmd_rename(void) return 0; } +#if 0 + This will become a hard link call. JRA. +/**************************************************************************** + Rename some file using the NT call. +****************************************************************************/ + +static int cmd_ntrename(void) +{ + pstring src,dest; + fstring buf,buf2; + + pstrcpy(src,cur_dir); + pstrcpy(dest,cur_dir); + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || + !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) { + d_printf("ntrename \n"); + return 1; + } + + pstrcat(src,buf); + pstrcat(dest,buf2); + + if (!cli_ntrename(cli, src, dest)) { + d_printf("%s doing an NT rename of files\n",cli_errstr(cli)); + return 1; + } + + return 0; +} +#endif + /**************************************************************************** Toggle the prompt flag. ****************************************************************************/ @@ -2168,6 +2204,10 @@ static struct {"more",cmd_more," view a remote file with your pager",{COMPL_REMOTE,COMPL_NONE}}, {"mput",cmd_mput," put all matching files",{COMPL_REMOTE,COMPL_NONE}}, {"newer",cmd_newer," only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}}, +#if 0 + /* This call will eventually morph into a hard link call. JRA */ + {"ntrename",cmd_ntrename," NT rename some files",{COMPL_REMOTE,COMPL_REMOTE}}, +#endif {"open",cmd_open," open a file",{COMPL_REMOTE,COMPL_NONE}}, {"print",cmd_print," print a file",{COMPL_NONE,COMPL_NONE}}, {"printmode",cmd_printmode," set the print mode",{COMPL_NONE,COMPL_NONE}}, diff --git a/source3/include/smb.h b/source3/include/smb.h index ab6f4c70d6..298944a0b1 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1155,6 +1155,12 @@ struct bitmap { /* Flag for NT transact rename call. */ #define RENAME_REPLACE_IF_EXISTS 1 +/* flags for SMBntrename call (from Samba4) */ +#define RENAME_FLAG_MOVE_CLUSTER_INFORMATION 0x102 /* ???? */ +#define RENAME_FLAG_HARD_LINK 0x103 +#define RENAME_FLAG_RENAME 0x104 +#define RENAME_FLAG_COPY 0x105 + /* Filesystem Attributes. */ #define FILE_CASE_SENSITIVE_SEARCH 0x00000001 #define FILE_CASE_PRESERVED_NAMES 0x00000002 diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index 178fd9c358..c3bdba30b1 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -245,6 +245,7 @@ copy an IP address from one buffer to another Make a filename into unix format. ****************************************************************************/ +#define IS_DIRECTORY_SEP(c) ((c) == '\\' || (c) == '/') #define unix_format(fname) string_replace(fname,'\\','/') #define unix_format_w(fname) string_replace_w(fname, UCS2_CHAR('\\'), UCS2_CHAR('/')) diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index c7f0cdb84b..9b766987ef 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -223,6 +223,44 @@ BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_ return True; } +/**************************************************************************** + NT Rename a file. +****************************************************************************/ + +BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fname_dst) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf, 4, 0, True); + + SCVAL(cli->outbuf,smb_com,SMBntrename); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); + SSVAL(cli->outbuf,smb_vwv1, RENAME_FLAG_RENAME); + + p = smb_buf(cli->outbuf); + *p++ = 4; + p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + *p++ = 4; + p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + if (cli_is_error(cli)) + return False; + + return True; +} + /**************************************************************************** Delete a file. ****************************************************************************/ diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 8aa02b57b6..128904800b 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1480,7 +1480,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { NTSTATUS status; - status = rename_internals(conn, new_name, old_name, True); + status = rename_internals(conn, new_name, old_name, 0, True); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); @@ -1499,7 +1499,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { NTSTATUS status; - status = rename_internals(conn, new_name, old_name, True); + status = rename_internals(conn, new_name, old_name, 0, True); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); @@ -1520,7 +1520,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { NTSTATUS status; - status = rename_internals(conn, new_name, old_name, True); + status = rename_internals(conn, new_name, old_name, 0, True); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); @@ -1542,7 +1542,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { NTSTATUS status; - status = rename_internals(conn, new_name, old_name, True); + status = rename_internals(conn, new_name, old_name, 0, True); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); @@ -1573,7 +1573,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]); if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) { NTSTATUS status; - status = rename_internals(conn, new_name, old_name, True); + status = rename_internals(conn, new_name, old_name, 0, True); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n", new_name, old_name)); diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 643e315c06..a71e8a806c 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -114,29 +114,30 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen DEBUG(5, ("unix_convert called on file \"%s\"\n", name)); /* - * Convert to basic unix format - removing \ chars and cleaning it up. + * Conversion to basic unix format is already done in check_path_syntax(). */ - unix_format(name); - unix_clean_name(name); - /* - * Names must be relative to the root of the service - trim any leading /. - * also trim trailing /'s. + * Names must be relative to the root of the service - any leading /. + * and trailing /'s should have been trimmed by check_path_syntax(). */ - trim_char(name,'/','/'); +#ifdef DEVELOPER + SMB_ASSERT(*name != '/'); +#endif /* * If we trimmed down to a single '\0' character * then we should use the "." directory to avoid * searching the cache, but not if we are in a * printing share. + * As we know this is valid we can return true here. */ if (!*name) { name[0] = '.'; name[1] = '\0'; + return(True); } /* @@ -154,19 +155,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen if (!case_sensitive && (!case_preserve || (mangle_is_8_3(name, False) && !short_case_preserve))) strnorm(name); - /* - * If we trimmed down to a single '\0' character - * then we will be using the "." directory. - * As we know this is valid we can return true here. - */ - - if(!*name) - return(True); - start = name; - while (start[0] == '.' && start[1] == '/') - start += 2; - pstrcpy(orig_path, name); if(!case_sensitive && stat_cache_lookup(conn, name, dirpath, &start, &st)) { diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 1afcf0af63..ac355ecd51 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -538,7 +538,7 @@ static int do_ntcreate_pipe_open(connection_struct *conn, char *p = NULL; NTSTATUS status; - srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE,&status); + srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) return ERROR_NT(status); @@ -659,7 +659,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib if(!dir_fsp->is_directory) { - srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE,&status); + srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBntcreateX); return ERROR_NT(status); @@ -701,13 +701,13 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib dir_name_len++; } - srvstr_get_path(inbuf, &fname[dir_name_len], smb_buf(inbuf), sizeof(fname)-dir_name_len, STR_TERMINATE,&status); + srvstr_get_path(inbuf, &fname[dir_name_len], smb_buf(inbuf), sizeof(fname)-dir_name_len, 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBntcreateX); return ERROR_NT(status); } } else { - srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE,&status); + srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBntcreateX); return ERROR_NT(status); @@ -1019,8 +1019,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha return ERROR_DOS(ERRDOS,ERRnoaccess); } - srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE); - status = check_path_syntax(fname); + srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); } @@ -1161,7 +1160,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o int smb_open_mode; int smb_attr; time_t c_time; - NTSTATUS nt_status; + NTSTATUS status; DEBUG(5,("call_nt_transact_create\n")); @@ -1227,11 +1226,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o return ERROR_DOS(ERRDOS,ERRbadfid); if(!dir_fsp->is_directory) { - - srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE); - nt_status = check_path_syntax(fname); - if (!NT_STATUS_IS_OK(nt_status)) { - return ERROR_NT(nt_status); + srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); } /* @@ -1260,17 +1257,18 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o dir_name_len++; } - srvstr_pull(inbuf, &fname[dir_name_len], params+53, sizeof(fname)-dir_name_len, - parameter_count-53, STR_TERMINATE); - nt_status = check_path_syntax(fname); - if (!NT_STATUS_IS_OK(nt_status)) { - return ERROR_NT(nt_status); + { + pstring tmpname; + srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } + pstrcat(fname, tmpname); } } else { - srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE); - nt_status = check_path_syntax(fname); - if (!NT_STATUS_IS_OK(nt_status)) { - return ERROR_NT(nt_status); + srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); } /* @@ -1396,10 +1394,10 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o * Now try and apply the desired SD. */ - if (sd_len && !NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION))) { + if (sd_len && !NT_STATUS_IS_OK(status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION))) { close_file(fsp,False); restore_case_semantics(file_attributes); - return ERROR_NT(nt_status); + return ERROR_NT(status); } restore_case_semantics(file_attributes); @@ -1519,17 +1517,31 @@ int reply_ntrename(connection_struct *conn, pstring newname; char *p; NTSTATUS status; + uint16 attrs = SVAL(inbuf,smb_vwv0); + uint16 rename_type = SVAL(inbuf,smb_vwv1); START_PROFILE(SMBntrename); + if (rename_type != RENAME_FLAG_RENAME) { + END_PROFILE(SMBntrename); + return ERROR_NT(NT_STATUS_ACCESS_DENIED); + } + p = smb_buf(inbuf) + 1; - p += srvstr_get_path(inbuf, name, p, sizeof(name), STR_TERMINATE,&status); + p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBntrename); return ERROR_NT(status); } + + if( strchr_m(name, ':')) { + /* Can't rename a stream. */ + END_PROFILE(SMBntrename); + return ERROR_NT(NT_STATUS_ACCESS_DENIED); + } + p++; - p += srvstr_get_path(inbuf, newname, p, sizeof(newname), STR_TERMINATE,&status); + p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBntrename); return ERROR_NT(status); @@ -1540,7 +1552,7 @@ int reply_ntrename(connection_struct *conn, DEBUG(3,("reply_ntrename : %s -> %s\n",name,newname)); - status = rename_internals(conn, name, newname, False); + status = rename_internals(conn, name, newname, attrs, False); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBntrename); return ERROR_NT(status); @@ -1628,14 +1640,13 @@ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *o fsp = file_fsp(params, 0); replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False; CHECK_FSP(fsp, conn); - srvstr_pull(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE); - status = check_path_syntax(new_name); + srvstr_get_path(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); } status = rename_internals(conn, fsp->fsp_name, - new_name, replace_if_exists); + new_name, 0, replace_if_exists); if (!NT_STATUS_IS_OK(status)) return ERROR_NT(status); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 836f95e179..051aaafb45 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -40,28 +40,117 @@ extern BOOL global_encrypted_passwords_negotiated; /**************************************************************************** Ensure we check the path in *exactly* the same way as W2K. + We're assuming here that '/' is not the second byte in any multibyte char + set (a safe assumption). '\\' *may* be the second byte in a multibyte char + set. ****************************************************************************/ -NTSTATUS check_path_syntax(const char *name) +static NTSTATUS check_path_syntax(pstring destname, const pstring srcname) { - while (*name == '\\' || *name == '/') - name++; - if (name[0] == '.' && name[1] == '\0') - return NT_STATUS_OBJECT_NAME_INVALID; - else if (name[0] == '.' && name[1] == '.' && - (name[2] == '\\' || name [2] == '/' || name[2] == '\0')) - return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; - return NT_STATUS_OK; + char *d = destname; + const char *s = srcname; + NTSTATUS ret = NT_STATUS_OK; + + while (*s) { + if (IS_DIRECTORY_SEP(*s)) { + /* + * Safe to assume is not the second part of a mb char as this is handled below. + */ + /* Eat multiple '/' or '\\' */ + while (IS_DIRECTORY_SEP(*s)) { + s++; + } + if ((d != destname) && (*s != '\0')) { + /* We only care about non-leading or trailing '/' or '\\' */ + *d++ = '/'; + } + } else if ((s[0] == '.') && (s[1] == '.') && (IS_DIRECTORY_SEP(s[2]) || s[2] == '\0')) { + /* Uh oh - "../" or "..\\" or "..\0" ! */ + + /* + * No mb char starts with '.' so we're safe checking the directory separator here. + */ + + /* If we just added a '/', delete it. */ + + if ((d > destname) && (*(d-1) == '/')) { + *(d-1) = '\0'; + if (d == (destname + 1)) { + d--; + } else { + d -= 2; + } + } + /* Are we at the start ? Can't go back further if so. */ + if (d == destname) { + return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; + } + /* Go back one level... */ + while (d > destname) { + if (*d == '/') + break; + d--; + } + s += 3; + } else if ((s[0] == '.') && IS_DIRECTORY_SEP(s[1])) { + + /* + * No mb char starts with '.' so we're safe checking the directory separator here. + */ + + /* "./" or ".\\" fails with a different error depending on where it is... */ + + if (s == srcname) { + ret = NT_STATUS_OBJECT_NAME_INVALID; + } else { + if (s[2] == '\0') { + return NT_STATUS_INVALID_PARAMETER; + } + ret = NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + s++; + } else { + if ((*s & 0x80) && IS_DIRECTORY_SEP(s[1])) { + /* + * Potential mb char with second char a directory separator. + * All the encodings we care about are 2 byte only, so do a + * conversion to unicode. If the 2 byte char won't convert then + * it's probably a one byte char with a real directory separator + * following, so only copy one byte. If it will convert then + * copy both bytes. + */ + uint16 ucs2_val; + if (convert_string(CH_UNIX, CH_UCS2, s, 2, &ucs2_val, 2) == 2) { + *d++ = *s++; + } + } + /* Just copy the char (or the second byte of the mb char). */ + *d++ = *s++; + } + } + *d = '\0'; + return ret; } /**************************************************************************** Pull a string and check the path - provide for error return. ****************************************************************************/ -size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len, int flags, NTSTATUS *err) +size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags, NTSTATUS *err) { - size_t ret = srvstr_pull_buf( inbuf, dest, src, dest_len, flags); - *err = check_path_syntax(dest); + pstring tmppath; + char *tmppath_ptr = tmppath; +#ifdef DEVELOPER + SMB_ASSERT(dest_len == sizeof(pstring)); +#endif + size_t ret; + + if (src_len == 0) { + ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags); + } else { + ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags); + } + *err = check_path_syntax(dest, tmppath); return ret; } @@ -414,7 +503,7 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size START_PROFILE(SMBchkpth); - srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE, &status); + srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBchkpth); return ERROR_NT(status); @@ -492,7 +581,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size START_PROFILE(SMBgetatr); p = smb_buf(inbuf) + 1; - p += srvstr_get_path(inbuf, fname, p, sizeof(fname), STR_TERMINATE,&status); + p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBgetatr); return ERROR_NT(status); @@ -567,7 +656,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size START_PROFILE(SMBsetatr); p = smb_buf(inbuf) + 1; - p += srvstr_get_path(inbuf, fname, p, sizeof(fname), STR_TERMINATE,&status); + p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBsetatr); return ERROR_NT(status); @@ -695,7 +784,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size maxentries = SVAL(inbuf,smb_vwv0); dirtype = SVAL(inbuf,smb_vwv1); p = smb_buf(inbuf) + 1; - p += srvstr_get_path(inbuf, path, p, sizeof(path), STR_TERMINATE,&nt_status); + p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &nt_status); if (!NT_STATUS_IS_OK(nt_status)) { END_PROFILE(SMBsearch); return ERROR_NT(nt_status); @@ -873,7 +962,7 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size outsize = set_message(outbuf,1,0,True); p = smb_buf(inbuf) + 1; - p += srvstr_get_path(inbuf, path, p, sizeof(path), STR_TERMINATE,&err); + p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &err); if (!NT_STATUS_IS_OK(err)) { END_PROFILE(SMBfclose); return ERROR_NT(err); @@ -925,7 +1014,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, share_mode = SVAL(inbuf,smb_vwv0); - srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), STR_TERMINATE,&status); + srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBopen); return ERROR_NT(status); @@ -1017,7 +1106,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt } /* XXXX we need to handle passed times, sattr and flags */ - srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE,&status); + srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBopenX); return ERROR_NT(status); @@ -1133,7 +1222,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, com = SVAL(inbuf,smb_com); createmode = SVAL(inbuf,smb_vwv0); - srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), STR_TERMINATE,&status); + srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBcreate); return ERROR_NT(status); @@ -1202,7 +1291,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, START_PROFILE(SMBctemp); createmode = SVAL(inbuf,smb_vwv0); - srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), STR_TERMINATE,&status); + srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBctemp); return ERROR_NT(status); @@ -1456,17 +1545,27 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) while ((dname = ReadDirName(dirptr))) { pstring fname; pstrcpy(fname,dname); + BOOL sys_direntry = False; /* Quick check for "." and ".." */ if (fname[0] == '.') { if (!fname[1] || (fname[1] == '.' && !fname[2])) { - continue; + if ((dirtype & aDIR)) { + sys_direntry = True; + } else { + continue; + } } } if(!mask_match(fname, mask, case_sensitive)) continue; + if (sys_direntry) { + error = NT_STATUS_OBJECT_NAME_INVALID; + continue; + } + slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); error = can_delete(fname,conn,dirtype,bad_path); if (!NT_STATUS_IS_OK(error)) @@ -1501,7 +1600,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size dirtype = SVAL(inbuf,smb_vwv0); - srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE,&status); + srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBunlink); return ERROR_NT(status); @@ -3054,7 +3153,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, NTSTATUS status; START_PROFILE(SMBmkdir); - srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE,&status); + srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBmkdir); return ERROR_NT(status); @@ -3224,7 +3323,7 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, NTSTATUS status; START_PROFILE(SMBrmdir); - srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), STR_TERMINATE,&status); + srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBrmdir); return ERROR_NT(status); @@ -3464,15 +3563,16 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char * code. ****************************************************************************/ -NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BOOL replace_if_exists) +NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint16 attrs, BOOL replace_if_exists) { pstring directory; pstring mask; - pstring newname_last_component; + pstring last_component_src; + pstring last_component_dest; char *p; BOOL has_wild; - BOOL bad_path1 = False; - BOOL bad_path2 = False; + BOOL bad_path_src = False; + BOOL bad_path_dest = False; int count=0; NTSTATUS error = NT_STATUS_OK; BOOL rc = True; @@ -3483,8 +3583,29 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BO ZERO_STRUCT(sbuf1); ZERO_STRUCT(sbuf2); - rc = unix_convert(name,conn,0,&bad_path1,&sbuf1); - rcdest = unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2); + + rc = unix_convert(name,conn,last_component_src,&bad_path_src,&sbuf1); + if (!rc && bad_path_src) { + if (ms_has_wild(last_component_src)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + + /* Quick check for "." and ".." */ + if (last_component_src[0] == '.') { + if (!last_component_src[1] || (last_component_src[1] == '.' && !last_component_src[2])) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + } + + rcdest = unix_convert(newname,conn,last_component_dest,&bad_path_dest,&sbuf2); + + /* Quick check for "." and ".." */ + if (last_component_dest[0] == '.') { + if (!last_component_dest[1] || (last_component_dest[1] == '.' && !last_component_dest[2])) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + } /* * Split the old name into directory and last component @@ -3540,9 +3661,9 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BO } DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \ -directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", +directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n", case_sensitive, case_preserve, short_case_preserve, directory, - newname, newname_last_component, is_short_name)); + newname, last_component_dest, is_short_name)); /* * Check for special case with case preserving and not @@ -3558,7 +3679,7 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", ((short_case_preserve == True) && (is_short_name == True))) && strcsequal(directory, newname)) { - pstring newname_modified_last_component; + pstring modified_last_component; /* * Get the last component of the modified name. @@ -3566,15 +3687,15 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", * character above. */ p = strrchr_m(newname,'/'); - pstrcpy(newname_modified_last_component,p+1); + pstrcpy(modified_last_component,p+1); - if(strcsequal(newname_modified_last_component, - newname_last_component) == False) { + if(strcsequal(modified_last_component, + last_component_dest) == False) { /* * Replace the modified last component with * the original. */ - pstrcpy(p+1, newname_last_component); + pstrcpy(p+1, last_component_dest); } } @@ -3609,14 +3730,9 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", return error; } - /* Quick check for "." and ".." */ - if (!bad_path2 && newname_last_component[0] == '.') { - if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { - DEBUG(10,("rename_internals: newname_last_component = '.' or '..'\n")); - return NT_STATUS_ACCESS_DENIED; - } - } - if (!rcdest && bad_path2) { + if (!rcdest && bad_path_dest) { + if (ms_has_wild(last_component_dest)) + return NT_STATUS_OBJECT_NAME_INVALID; return NT_STATUS_OBJECT_PATH_NOT_FOUND; } @@ -3669,17 +3785,6 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", const char *dname; pstring destname; - /* Quick check for "." and ".." */ - if (!bad_path2 && newname_last_component[0] == '.') { - if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { - DEBUG(10,("rename_internals: newname_last_component = '.' or '..'\n")); - return NT_STATUS_ACCESS_DENIED; - } - } - if (!rcdest && bad_path2) { - return NT_STATUS_OBJECT_PATH_NOT_FOUND; - } - if (check_name(directory,conn)) dirptr = OpenDir(conn, directory, True); @@ -3692,19 +3797,29 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", while ((dname = ReadDirName(dirptr))) { pstring fname; + BOOL sysdir_entry = False; pstrcpy(fname,dname); /* Quick check for "." and ".." */ if (fname[0] == '.') { if (!fname[1] || (fname[1] == '.' && !fname[2])) { - continue; + if (attrs & aDIR) { + sysdir_entry = True; + } else { + continue; + } } } if(!mask_match(fname, mask, case_sensitive)) continue; + if (sysdir_entry) { + error = NT_STATUS_OBJECT_NAME_INVALID; + continue; + } + error = NT_STATUS_ACCESS_DENIED; slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname); if (!vfs_object_exist(conn, fname, &sbuf1)) { @@ -3735,11 +3850,20 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", if (!SMB_VFS_RENAME(conn,fname,destname)) { rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname); count++; + error = NT_STATUS_OK; } DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname)); } CloseDir(dirptr); } + + if (!NT_STATUS_EQUAL(error,NT_STATUS_NO_SUCH_FILE)) { + if (!rcdest && bad_path_dest) { + if (ms_has_wild(last_component_dest)) + return NT_STATUS_OBJECT_NAME_INVALID; + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + } } if (count == 0 && NT_STATUS_IS_OK(error)) { @@ -3760,18 +3884,19 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, pstring name; pstring newname; char *p; + uint16 attrs = SVAL(inbuf,smb_vwv0); NTSTATUS status; START_PROFILE(SMBmv); p = smb_buf(inbuf) + 1; - p += srvstr_get_path(inbuf, name, p, sizeof(name), STR_TERMINATE,&status); + p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBmv); return ERROR_NT(status); } p++; - p += srvstr_get_path(inbuf, newname, p, sizeof(newname), STR_TERMINATE,&status); + p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBmv); return ERROR_NT(status); @@ -3782,7 +3907,7 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, DEBUG(3,("reply_mv : %s -> %s\n",name,newname)); - status = rename_internals(conn, name, newname, False); + status = rename_internals(conn, name, newname, attrs, False); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBmv); return ERROR_NT(status); @@ -3909,12 +4034,12 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, *directory = *mask = 0; p = smb_buf(inbuf); - p += srvstr_get_path(inbuf, name, p, sizeof(name), STR_TERMINATE,&status); + p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBcopy); return ERROR_NT(status); } - p += srvstr_get_path(inbuf, newname, p, sizeof(newname), STR_TERMINATE,&status); + p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBcopy); return ERROR_NT(status); @@ -4074,7 +4199,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return ERROR_DOS(ERRDOS,ERRnoaccess); } - srvstr_get_path(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), STR_TERMINATE,&status); + srvstr_get_path(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(pathworks_setdir); return ERROR_NT(status); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 5fbc5ce6ee..1d580e6f5b 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -228,6 +228,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i int smb_action = 0; BOOL bad_path = False; files_struct *fsp; + NTSTATUS status; /* * Ensure we have enough parameters to perform the operation. @@ -248,7 +249,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i open_size = IVAL(params,14); pname = ¶ms[28]; - srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE); + srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n", fname,open_mode, open_attr, open_ofun, open_size)); @@ -939,6 +943,7 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb int space_remaining; BOOL bad_path = False; SMB_STRUCT_STAT sbuf; + NTSTATUS ntstatus = NT_STATUS_OK; if (total_params < 12) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); @@ -968,7 +973,10 @@ close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n", return(ERROR_DOS(ERRDOS,ERRunknownlevel)); } - srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE); + srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus); + if (!NT_STATUS_IS_OK(ntstatus)) { + return ERROR_NT(ntstatus); + } RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf); @@ -1151,13 +1159,17 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu BOOL dont_descend = False; BOOL out_of_space = False; int space_remaining; + NTSTATUS ntstatus = NT_STATUS_OK; if (total_params < 12) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); *mask = *directory = *resume_name = 0; - srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE); + srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus); + if (!NT_STATUS_IS_OK(ntstatus)) { + return ERROR_NT(ntstatus); + } DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \ close_after_request=%d, close_if_end = %d requires_resume_key = %d \ @@ -1909,6 +1921,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, desired_access = fsp->desired_access; } } else { + NTSTATUS status = NT_STATUS_OK; + /* qpathinfo */ if (total_params < 6) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); @@ -1917,7 +1931,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn, DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level)); - srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE); + srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } RESOLVE_DFSPATH(fname, conn, inbuf, outbuf); @@ -2483,6 +2500,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE; gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE; mode_t unixmode = 0; + NTSTATUS status = NT_STATUS_OK; if (!params) return ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -2540,7 +2558,10 @@ static int call_trans2setfilepathinfo(connection_struct *conn, return(ERROR_DOS(ERRDOS,ERRinvalidparam)); info_level = SVAL(params,0); - srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE); + srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } unix_convert(fname,conn,0,&bad_path,&sbuf); /* @@ -2761,7 +2782,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */ { BOOL delete_on_close; - NTSTATUS status; if (total_data < 1) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); @@ -2948,7 +2968,10 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (VALID_STAT(sbuf)) return(ERROR_DOS(ERRDOS,ERRbadpath)); - srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE); + srvstr_get_path(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } if (ensure_link_is_safe(conn, link_dest, link_dest) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2973,7 +2996,10 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (VALID_STAT(sbuf)) return(ERROR_DOS(ERRDOS,ERRbadpath)); - srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE); + srvstr_get_path(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } if (ensure_link_is_safe(conn, link_dest, link_dest) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2996,7 +3022,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", pstring newname; pstring base_name; char *p; - NTSTATUS status; if (total_data < 12) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); @@ -3004,10 +3029,13 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", overwrite = (CVAL(pdata,0) ? True : False); root_fid = IVAL(pdata,4); len = IVAL(pdata,8); - srvstr_pull(inbuf, newname, &pdata[12], sizeof(newname), len, 0); + srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } - /* Check the new name has no '\' characters. */ - if (strchr_m(newname, '\\') || strchr_m(newname, '/')) + /* Check the new name has no '/' characters. */ + if (strchr_m(newname, '/')) return ERROR_NT(NT_STATUS_NOT_SUPPORTED); RESOLVE_DFSPATH(newname, conn, inbuf, outbuf); @@ -3028,10 +3056,11 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", } else { DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n", fname, newname )); - status = rename_internals(conn, fname, base_name, overwrite); + status = rename_internals(conn, fname, base_name, 0, overwrite); } - if (!NT_STATUS_IS_OK(status)) + if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); + } process_pending_change_notify_queue((time_t)0); SSVAL(params,0,0); send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); @@ -3171,6 +3200,7 @@ static int call_trans2mkdir(connection_struct *conn, int ret = -1; SMB_STRUCT_STAT sbuf; BOOL bad_path = False; + NTSTATUS status = NT_STATUS_OK; if (!CAN_WRITE(conn)) return ERROR_DOS(ERRSRV,ERRaccess); @@ -3178,7 +3208,10 @@ static int call_trans2mkdir(connection_struct *conn, if (total_params < 4) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); - srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE); + srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } DEBUG(3,("call_trans2mkdir : name = %s\n", directory)); @@ -3290,6 +3323,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, pstring pathname; int reply_size = 0; int max_referral_level; + NTSTATUS status = NT_STATUS_OK; DEBUG(10,("call_trans2getdfsreferral\n")); @@ -3301,7 +3335,10 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, if(!lp_host_msdfs()) return ERROR_DOS(ERRDOS,ERRbadfunc); - srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE); + srvstr_get_path(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0) return UNIXERROR(ERRDOS,ERRbadfile); -- cgit From 1fcc87b8148be2ca7fa73f18a19c677c3f4fbab4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Mar 2004 23:14:21 +0000 Subject: Added client "hardlink" commant to test doing NT rename with hard links. Added hardlink_internals() code - UNIX extensions now use this too. Jeremy. (This used to be commit 3f2b9f10dec58d3e3ae463e3804d96052fb27a4d) --- source3/client/client.c | 18 +++------ source3/libsmb/clifile.c | 44 +++++++++++++++++++++- source3/smbd/nttrans.c | 9 ++++- source3/smbd/trans2.c | 95 +++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 136 insertions(+), 30 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index d0bc01655f..3a189a13e7 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1773,13 +1773,11 @@ static int cmd_rename(void) return 0; } -#if 0 - This will become a hard link call. JRA. /**************************************************************************** - Rename some file using the NT call. + Hard link files using the NT call. ****************************************************************************/ -static int cmd_ntrename(void) +static int cmd_hardlink(void) { pstring src,dest; fstring buf,buf2; @@ -1789,21 +1787,20 @@ static int cmd_ntrename(void) if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) { - d_printf("ntrename \n"); + d_printf("hardlink \n"); return 1; } pstrcat(src,buf); pstrcat(dest,buf2); - if (!cli_ntrename(cli, src, dest)) { - d_printf("%s doing an NT rename of files\n",cli_errstr(cli)); + if (!cli_nt_hardlink(cli, src, dest)) { + d_printf("%s doing an NT hard link of files\n",cli_errstr(cli)); return 1; } return 0; } -#endif /**************************************************************************** Toggle the prompt flag. @@ -2191,6 +2188,7 @@ static struct {"du",cmd_du," computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}}, {"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}}, {"get",cmd_get," [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}}, + {"hardlink",cmd_hardlink," create a Windows hard link",{COMPL_REMOTE,COMPL_REMOTE}}, {"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}}, {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}}, {"lcd",cmd_lcd,"[directory] change/report the local current working directory",{COMPL_LOCAL,COMPL_NONE}}, @@ -2204,10 +2202,6 @@ static struct {"more",cmd_more," view a remote file with your pager",{COMPL_REMOTE,COMPL_NONE}}, {"mput",cmd_mput," put all matching files",{COMPL_REMOTE,COMPL_NONE}}, {"newer",cmd_newer," only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}}, -#if 0 - /* This call will eventually morph into a hard link call. JRA */ - {"ntrename",cmd_ntrename," NT rename some files",{COMPL_REMOTE,COMPL_REMOTE}}, -#endif {"open",cmd_open," open a file",{COMPL_REMOTE,COMPL_NONE}}, {"print",cmd_print," print a file",{COMPL_NONE,COMPL_NONE}}, {"printmode",cmd_printmode," set the print mode",{COMPL_NONE,COMPL_NONE}}, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 9b766987ef..a3fa811e29 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -36,16 +36,18 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, cons pstring data; char *rparam=NULL, *rdata=NULL; char *p; + size_t srclen = 2*(strlen(fname_src)+1); + size_t destlen = 2*(strlen(fname_dst) + 1); memset(param, 0, sizeof(param)); SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK); p = ¶m[6]; - p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname_src, MIN(srclen, sizeof(param)-6), STR_TERMINATE); param_len = PTR_DIFF(p, param); p = data; - p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname_dst, MIN(destlen,sizeof(data)), STR_TERMINATE); data_len = PTR_DIFF(p, data); if (!cli_send_trans(cli, SMBtrans2, @@ -261,6 +263,44 @@ BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fnam return True; } +/**************************************************************************** + NT hardlink a file. +****************************************************************************/ + +BOOL cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf, 4, 0, True); + + SCVAL(cli->outbuf,smb_com,SMBntrename); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); + SSVAL(cli->outbuf,smb_vwv1, RENAME_FLAG_HARD_LINK); + + p = smb_buf(cli->outbuf); + *p++ = 4; + p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + *p++ = 4; + p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + if (cli_is_error(cli)) + return False; + + return True; +} + /**************************************************************************** Delete a file. ****************************************************************************/ diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index ac355ecd51..079027a5c5 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1522,7 +1522,7 @@ int reply_ntrename(connection_struct *conn, START_PROFILE(SMBntrename); - if (rename_type != RENAME_FLAG_RENAME) { + if ((rename_type != RENAME_FLAG_RENAME) && (rename_type != RENAME_FLAG_HARD_LINK)) { END_PROFILE(SMBntrename); return ERROR_NT(NT_STATUS_ACCESS_DENIED); } @@ -1552,7 +1552,12 @@ int reply_ntrename(connection_struct *conn, DEBUG(3,("reply_ntrename : %s -> %s\n",name,newname)); - status = rename_internals(conn, name, newname, attrs, False); + if (rename_type == RENAME_FLAG_RENAME) { + status = rename_internals(conn, name, newname, attrs, False); + } else { + status = hardlink_internals(conn, name, newname); + } + if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBntrename); return ERROR_NT(status); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 1d580e6f5b..e2df517f40 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2477,6 +2477,82 @@ static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in return 0; } +/**************************************************************************** + Set a hard link (called by UNIX extensions and by NT rename with HARD link + code. +****************************************************************************/ + +NTSTATUS hardlink_internals(connection_struct *conn, char *name, char *newname) +{ + BOOL bad_path_src = False; + BOOL bad_path_dest = False; + SMB_STRUCT_STAT sbuf1, sbuf2; + BOOL rc, rcdest; + pstring last_component_src; + pstring last_component_dest; + NTSTATUS status = NT_STATUS_OK; + + ZERO_STRUCT(sbuf1); + ZERO_STRUCT(sbuf2); + + /* No wildcards. */ + if (ms_has_wild(name) || ms_has_wild(newname)) { + return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; + } + + rc = unix_convert(name,conn,last_component_src,&bad_path_src,&sbuf1); + if (!rc && bad_path_src) { + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + + /* Quick check for "." and ".." */ + if (last_component_src[0] == '.') { + if (!last_component_src[1] || (last_component_src[1] == '.' && !last_component_src[2])) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + } + + /* source must already exist. */ + if (!VALID_STAT(sbuf1)) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + rcdest = unix_convert(newname,conn,last_component_dest,&bad_path_dest,&sbuf2); + if (!rcdest && bad_path_dest) { + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + + /* Quick check for "." and ".." */ + if (last_component_dest[0] == '.') { + if (!last_component_dest[1] || (last_component_dest[1] == '.' && !last_component_dest[2])) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + } + + /* Disallow if already exists. */ + if (VALID_STAT(sbuf2)) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + /* No links from a directory. */ + if (S_ISDIR(sbuf1.st_mode)) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + + if (ensure_link_is_safe(conn, newname, newname) != 0) + return NT_STATUS_ACCESS_DENIED; + + DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", name, newname )); + + if (SMB_VFS_LINK(conn,name,newname) != 0) { + status = map_nt_error_from_unix(errno); + DEBUG(3,("hardlink_internals: Error %s link %s -> %s\n", + nt_errstr(status), name,newname)); + } + + return status; +} + /**************************************************************************** Reply to a TRANS2_SETFILEINFO (set file info by fileid). ****************************************************************************/ @@ -2964,10 +3040,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (!lp_symlinks(SNUM(conn))) return(ERROR_DOS(ERRDOS,ERRnoaccess)); - /* Disallow if already exists. */ - if (VALID_STAT(sbuf)) - return(ERROR_DOS(ERRDOS,ERRbadpath)); - srvstr_get_path(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); @@ -2991,24 +3063,19 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", pstring link_dest; /* Set a hard link. */ - - /* Disallow if already exists. */ - if (VALID_STAT(sbuf)) - return(ERROR_DOS(ERRDOS,ERRbadpath)); - srvstr_get_path(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); } - if (ensure_link_is_safe(conn, link_dest, link_dest) != 0) - return(UNIXERROR(ERRDOS,ERRnoaccess)); - DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n", fname, link_dest )); - if (SMB_VFS_LINK(conn,link_dest,fname) != 0) - return(UNIXERROR(ERRDOS,ERRnoaccess)); + status = hardlink_internals(conn, fname, link_dest); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } + SSVAL(params,0,0); send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); return(-1); -- cgit From 0b975dd7c64e94c7bcad9d7628005b16e9006424 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 4 Mar 2004 15:19:00 +0000 Subject: another fix for bug 761; don't default to bsd printing on linux (This used to be commit 29bc83080f47b2f945686e706f2cfef221ac3795) --- source3/include/includes.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/source3/include/includes.h b/source3/include/includes.h index a594e309df..01822d7c00 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -45,15 +45,6 @@ #undef HAVE_TERMIOS_H #endif -#ifdef LINUX -#ifndef DEFAULT_PRINTING -#define DEFAULT_PRINTING PRINT_BSD -#endif -#ifndef PRINTCAP_NAME -#define PRINTCAP_NAME "/etc/printcap" -#endif -#endif - #ifdef __GNUC__ /** Use gcc attribute to check printf fns. a1 is the 1-based index of * the parameter containing the format, and a2 the index of the first -- cgit From 4c00877894953d0d58663a9f9012eb2beeff6268 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 4 Mar 2004 16:00:16 +0000 Subject: BUG 848: don't create winbind local users/groups that already exist in the tdb (This used to be commit 00c998c5030560d096d7f3c0f9d89ce18e2d006b) --- source3/nsswitch/winbindd_acct.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/source3/nsswitch/winbindd_acct.c b/source3/nsswitch/winbindd_acct.c index 28434496ce..2f94a2efd0 100644 --- a/source3/nsswitch/winbindd_acct.c +++ b/source3/nsswitch/winbindd_acct.c @@ -1007,7 +1007,7 @@ enum winbindd_result winbindd_create_user(struct winbindd_cli_state *state) { char *user, *group; unid_t id; - WINBINDD_PW pw; + WINBINDD_PW pw, *pw_check; WINBINDD_GR *wb_grp; struct group *unix_grp; gid_t primary_gid; @@ -1028,6 +1028,13 @@ enum winbindd_result winbindd_create_user(struct winbindd_cli_state *state) DEBUG(3, ("[%5lu]: create_user: user=>(%s), group=>(%s)\n", (unsigned long)state->pid, user, group)); + + if ( (pw_check=wb_getpwnam(user)) != NULL ) { + DEBUG(0,("winbindd_create_user: Refusing to create user that already exists (%s)\n", + user)); + return WINBINDD_ERROR; + } + if ( !*group ) group = lp_template_primary_group(); @@ -1103,7 +1110,7 @@ enum winbindd_result winbindd_create_group(struct winbindd_cli_state *state) { char *group; unid_t id; - WINBINDD_GR grp; + WINBINDD_GR grp, *grp_check; uint32 flags = state->request.flags; uint32 rid; @@ -1118,7 +1125,13 @@ enum winbindd_result winbindd_create_group(struct winbindd_cli_state *state) DEBUG(3, ("[%5lu]: create_group: (%s)\n", (unsigned long)state->pid, group)); - /* get a new uid */ + if ( (grp_check=wb_getgrnam(group)) != NULL ) { + DEBUG(0,("winbindd_create_group: Refusing to create group that already exists (%s)\n", + group)); + return WINBINDD_ERROR; + } + + /* get a new gid */ if ( !NT_STATUS_IS_OK(idmap_allocate_id( &id, ID_GROUPID)) ) { DEBUG(0,("winbindd_create_group: idmap_allocate_id() failed!\n")); -- cgit From a6bbc98a49ee489753a65a5feb5cfe3089ff46d8 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 4 Mar 2004 16:24:15 +0000 Subject: Fix build farm, older compilers won't let you declare variables right in the middle of the code. I just love catching jra on stuff like this, after all the crap I've done. :-) (This used to be commit 217791cab21b79fdbe2ddb96079fb9abb8545dd7) --- source3/smbd/reply.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 051aaafb45..c0d5234f47 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1544,8 +1544,8 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) while ((dname = ReadDirName(dirptr))) { pstring fname; - pstrcpy(fname,dname); BOOL sys_direntry = False; + pstrcpy(fname,dname); /* Quick check for "." and ".." */ if (fname[0] == '.') { -- cgit From 600327d849bef7a20e7e82e9cf237e6b0be40d12 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 4 Mar 2004 17:47:44 +0000 Subject: Fix typo. Volker (This used to be commit 6287141f10e6c774990b4fdf65bfd2a55afca35a) --- source3/utils/net_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 19825ff51b..76e367e32c 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1542,7 +1542,7 @@ rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name, &group_sid, argv[1]); if (!NT_STATUS_IS_OK(result)) { - d_printf("Could not add %s to %s: %s\n", + d_printf("Could not del %s from %s: %s\n", argv[1], argv[0], nt_errstr(result)); } return result; -- cgit From e9e6bd66cdc56f6369b2a4f3b2d9f1477e33899e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 4 Mar 2004 17:50:44 +0000 Subject: Another typo, sorry for samba-cvs spam :-) (This used to be commit da59bab769dac3702dbddd6ad718f918befee6db) --- source3/utils/net_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 76e367e32c..46835d080d 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1531,7 +1531,7 @@ rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name, &group_sid, argv[1]); if (!NT_STATUS_IS_OK(result)) { - d_printf("Could not del %s to %s: %s\n", + d_printf("Could not del %s from %s: %s\n", argv[1], argv[0], nt_errstr(result)); } return result; -- cgit From 381485668af40f83f17139c9f79772480cd62580 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 4 Mar 2004 17:59:25 +0000 Subject: There's a specific error message NT_STATUS_ALIAS_EXISTS. (This used to be commit 0ad00bce0752373a1ac471f6629a5e64ee5af280) --- source3/rpc_server/srv_samr_nt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 15a4cf1ae4..42d19271e1 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3999,7 +3999,7 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S /* check if group already exists */ if ( (grp=getgrnam(name)) != NULL) - return NT_STATUS_GROUP_EXISTS; + return NT_STATUS_ALIAS_EXISTS; /* we can create the UNIX group */ if (smb_create_group(name, &gid) != 0) -- cgit From 20729772874ebdecbac5810a795200acf912ecf6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 4 Mar 2004 18:17:54 +0000 Subject: BUG 1080: fix declaration of SMB_BIG_UINT (This used to be commit 0b17a4105ecbad26b6bb79ed8148495c02518430) --- source3/include/includes.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source3/include/includes.h b/source3/include/includes.h index 01822d7c00..3ae5d0b201 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -610,6 +610,18 @@ typedef int socklen_t; # endif #endif +#if defined(HAVE_LONGLONG) +#define SMB_BIG_UINT unsigned long long +#define SMB_BIG_INT long long +#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32)) +#else +#define SMB_BIG_UINT unsigned long +#define SMB_BIG_INT long +#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0)) +#endif + +#define SMB_BIG_UINT_BITS (sizeof(SMB_BIG_UINT)*8) + /* this should really be a 64 bit type if possible */ #define br_off SMB_BIG_UINT @@ -700,18 +712,6 @@ typedef int socklen_t; # endif #endif -#if defined(HAVE_LONGLONG) -#define SMB_BIG_UINT unsigned long long -#define SMB_BIG_INT long long -#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32)) -#else -#define SMB_BIG_UINT unsigned long -#define SMB_BIG_INT long -#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0)) -#endif - -#define SMB_BIG_UINT_BITS (sizeof(SMB_BIG_UINT)*8) - #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif -- cgit From 33f0b530cf0a58118567e534ec3a7620ca8a2878 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 4 Mar 2004 18:35:05 +0000 Subject: BUG 1015: patch from jmcd to fix statfs redeclaration of statfs struct on ppc (This used to be commit d9a9e214a8dd3b79284f4cff6052210b758bbf72) --- source3/include/includes.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/include/includes.h b/source3/include/includes.h index 3ae5d0b201..c5a7b459be 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -338,8 +338,9 @@ #ifdef HAVE_SYS_CAPABILITY_H -#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) +#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H) #define _I386_STATFS_H +#define _PPC_STATFS_H #define BROKEN_REDHAT_7_STATFS_WORKAROUND #endif @@ -347,6 +348,7 @@ #ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND #undef _I386_STATFS_H +#undef _PPC_STATFS_H #undef BROKEN_REDHAT_7_STATFS_WORKAROUND #endif -- cgit From 26c41cb6d71f229a8dd2c7439c85de99f5f1e050 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Mar 2004 18:55:35 +0000 Subject: Fix my breakage of NT pipes from the previous patch (sorry). Use the original srvstr_pull_buf() function to get the pipename not srvstr_get_path(). Jeremy. (This used to be commit ac5e0c4bb686e2aaccc9b70f240f79747fd48cd8) --- source3/smbd/nttrans.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 079027a5c5..4a9db06c87 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -536,11 +536,8 @@ static int do_ntcreate_pipe_open(connection_struct *conn, int ret; int pnum = -1; char *p = NULL; - NTSTATUS status; - srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status); - if (!NT_STATUS_IS_OK(status)) - return ERROR_NT(status); + srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE); if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) return ret; -- cgit From 09325be439d7c976aadd2db2c2905f97b5af9ba6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Mar 2004 01:37:25 +0000 Subject: all_string_sub() is broken as it doesn't handle mb chars correctly (and so breaks when substitution '/' and '\'). It's used by unix_clean_name(), which is used by reduce_name, which is used by check_name() (phew!). Now that we know all filenames passed to check_name() are in a "good" format (no double slashes, all '\\' chars translated to '/' etc.) due to the new check_path_syntax() we can avoid calling reduce_name unless widelinks are denied. After this check-in I can fix all_string_sub() to handle mb chars correctly as it won't be in the direct path in the main path handling code. Jeremy. (This used to be commit bce0678331aa4746181389e0f91f11fb2a6dadcb) --- source3/smbd/filename.c | 6 ++++-- source3/smbd/vfs.c | 17 +---------------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index a71e8a806c..8300674d61 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -387,7 +387,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen BOOL check_name(pstring name,connection_struct *conn) { - BOOL ret; + BOOL ret = True; errno = 0; @@ -398,7 +398,9 @@ BOOL check_name(pstring name,connection_struct *conn) } } - ret = reduce_name(conn,name,conn->connectpath,lp_widelinks(SNUM(conn))); + if (!lp_widelinks(SNUM(conn))) { + ret = reduce_name(conn,name,conn->connectpath); + } /* Check if we are allowing users to follow symlinks */ /* Patch from David Clerc diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 2f981c743f..284e24e7b1 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -845,10 +845,9 @@ static BOOL readlink_check(connection_struct *conn, const char *dir, char *name) Reduce a file name, removing .. elements and checking that it is below dir in the heirachy. This uses vfs_GetWd() and so must be run on the system that has the referenced file system. - Widelinks are allowed if widelinks is true. ********************************************************************/ -BOOL reduce_name(connection_struct *conn, pstring s, const char *dir,BOOL widelinks) +BOOL reduce_name(connection_struct *conn, pstring s, const char *dir) { #ifndef REDUCE_PATHS return True; @@ -862,20 +861,6 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir,BOOL wideli *dir2 = *wd = *base_name = *newname = 0; - if (widelinks) { - unix_clean_name(s); - /* can't have a leading .. */ - if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/')) { - DEBUG(3,("Illegal file name? (%s)\n",s)); - return(False); - } - - if (strlen(s) == 0) - pstrcpy(s,"./"); - - return(True); - } - DEBUG(3,("reduce_name [%s] [%s]\n",s,dir)); /* remove any double slashes */ -- cgit From 19e94da7602a69fa2dce33b64fadfbb1fce40c95 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 5 Mar 2004 17:21:45 +0000 Subject: Add -O (write downloaded files to stdout), based on patch from Bas van Sisseren (This used to be commit a90df1c170a168092e0c90f684ea968bd1f6f768) --- source3/utils/smbget.c | 145 +++++++++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 65 deletions(-) diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c index ab6e368c70..64630bba8f 100644 --- a/source3/utils/smbget.c +++ b/source3/utils/smbget.c @@ -41,7 +41,7 @@ off_t total_bytes = 0; #define SMB_DEFAULT_BLOCKSIZE 64000 const char *username = NULL, *password = NULL, *workgroup = NULL; -int nonprompt = 0, quiet = 0, dots = 0, keep_permissions = 0, verbose = 0; +int nonprompt = 0, quiet = 0, dots = 0, keep_permissions = 0, verbose = 0, send_stdout = 0; int blocksize = SMB_DEFAULT_BLOCKSIZE; int smb_download_file(const char *base, const char *name, int recursive, int resume, char *outfile); @@ -51,7 +51,6 @@ int get_num_cols(void) #ifdef TIOCGWINSZ struct winsize ws; if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) { - perror("ioctl"); return 0; } return ws.ws_col; @@ -300,74 +299,81 @@ int smb_download_file(const char *base, const char *name, int recursive, int res if(newpath[0] == '/')newpath++; /* Open local file and, if necessary, resume */ - localhandle = open(newpath, O_CREAT | O_NONBLOCK | O_RDWR | (!resume?O_EXCL:0), 0755); - if(localhandle < 0) { - fprintf(stderr, "Can't open %s: %s\n", newpath, strerror(errno)); - smbc_close(remotehandle); - return 0; - } + if(!send_stdout) { + localhandle = open(newpath, O_CREAT | O_NONBLOCK | O_RDWR | (!resume?O_EXCL:0), 0755); + if(localhandle < 0) { + fprintf(stderr, "Can't open %s: %s\n", newpath, strerror(errno)); + smbc_close(remotehandle); + return 0; + } - fstat(localhandle, &localstat); + fstat(localhandle, &localstat); - start_offset = localstat.st_size; + start_offset = localstat.st_size; - if(localstat.st_size && localstat.st_size == remotestat.st_size) { - if(verbose)fprintf(stderr, "%s is already downloaded completely.\n", path); - else if(!quiet)fprintf(stderr, "%s\n", path); - smbc_close(remotehandle); - close(localhandle); - return 1; - } - - if(localstat.st_size > RESUME_CHECK_OFFSET && remotestat.st_size > RESUME_CHECK_OFFSET) { - offset_download = localstat.st_size - RESUME_DOWNLOAD_OFFSET; - offset_check = localstat.st_size - RESUME_CHECK_OFFSET; - if(verbose)printf("Trying to start resume of %s at "OFF_T_FORMAT"\n" - "At the moment "OFF_T_FORMAT" of "OFF_T_FORMAT" bytes have been retrieved\n", newpath, offset_check, - localstat.st_size, remotestat.st_size); - } - - if(offset_check) { - off_t off1, off2; - /* First, check all bytes from offset_check to offset_download */ - off1 = lseek(localhandle, offset_check, SEEK_SET); - if(off1 < 0) { - fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in local file %s\n", offset_check, newpath); - smbc_close(remotehandle); close(localhandle); - return 0; + if(localstat.st_size && localstat.st_size == remotestat.st_size) { + if(verbose)fprintf(stderr, "%s is already downloaded completely.\n", path); + else if(!quiet)fprintf(stderr, "%s\n", path); + smbc_close(remotehandle); + close(localhandle); + return 1; } - off2 = smbc_lseek(remotehandle, offset_check, SEEK_SET); - if(off2 < 0) { - fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in remote file %s\n", offset_check, newpath); - smbc_close(remotehandle); close(localhandle); - return 0; + if(localstat.st_size > RESUME_CHECK_OFFSET && remotestat.st_size > RESUME_CHECK_OFFSET) { + offset_download = localstat.st_size - RESUME_DOWNLOAD_OFFSET; + offset_check = localstat.st_size - RESUME_CHECK_OFFSET; + if(verbose)printf("Trying to start resume of %s at "OFF_T_FORMAT"\n" + "At the moment "OFF_T_FORMAT" of "OFF_T_FORMAT" bytes have been retrieved\n", newpath, offset_check, + localstat.st_size, remotestat.st_size); } - if(off1 != off2) { - fprintf(stderr, "Offset in local and remote files is different (local: "OFF_T_FORMAT", remote: "OFF_T_FORMAT")\n", off1, off2); - return 0; - } + if(offset_check) { + off_t off1, off2; + /* First, check all bytes from offset_check to offset_download */ + off1 = lseek(localhandle, offset_check, SEEK_SET); + if(off1 < 0) { + fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in local file %s\n", offset_check, newpath); + smbc_close(remotehandle); close(localhandle); + return 0; + } - if(smbc_read(remotehandle, checkbuf[0], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { - fprintf(stderr, "Can't read %d bytes from remote file %s\n", RESUME_CHECK_SIZE, path); - smbc_close(remotehandle); close(localhandle); - return 0; - } + off2 = smbc_lseek(remotehandle, offset_check, SEEK_SET); + if(off2 < 0) { + fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in remote file %s\n", offset_check, newpath); + smbc_close(remotehandle); close(localhandle); + return 0; + } - if(read(localhandle, checkbuf[1], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { - fprintf(stderr, "Can't read %d bytes from local file %s\n", RESUME_CHECK_SIZE, name); - smbc_close(remotehandle); close(localhandle); - return 0; - } + if(off1 != off2) { + fprintf(stderr, "Offset in local and remote files is different (local: "OFF_T_FORMAT", remote: "OFF_T_FORMAT")\n", off1, off2); + return 0; + } - if(memcmp(checkbuf[0], checkbuf[1], RESUME_CHECK_SIZE) == 0) { - if(verbose)printf("Current local and remote file appear to be the same. Starting download from offset "OFF_T_FORMAT"\n", offset_download); - } else { - fprintf(stderr, "Local and remote file appear to be different, not doing resume for %s\n", path); - smbc_close(remotehandle); close(localhandle); - return 0; + if(smbc_read(remotehandle, checkbuf[0], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { + fprintf(stderr, "Can't read %d bytes from remote file %s\n", RESUME_CHECK_SIZE, path); + smbc_close(remotehandle); close(localhandle); + return 0; + } + + if(read(localhandle, checkbuf[1], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { + fprintf(stderr, "Can't read %d bytes from local file %s\n", RESUME_CHECK_SIZE, name); + smbc_close(remotehandle); close(localhandle); + return 0; + } + + if(memcmp(checkbuf[0], checkbuf[1], RESUME_CHECK_SIZE) == 0) { + if(verbose)printf("Current local and remote file appear to be the same. Starting download from offset "OFF_T_FORMAT"\n", offset_download); + } else { + fprintf(stderr, "Local and remote file appear to be different, not doing resume for %s\n", path); + smbc_close(remotehandle); close(localhandle); + return 0; + } } + } else { + localhandle = STDOUT_FILENO; + start_offset = 0; + offset_download = 0; + offset_check = 0; } readbuf = malloc(blocksize); @@ -377,7 +383,8 @@ int smb_download_file(const char *base, const char *name, int recursive, int res ssize_t bytesread = smbc_read(remotehandle, readbuf, blocksize); if(bytesread < 0) { fprintf(stderr, "Can't read %d bytes at offset "OFF_T_FORMAT", file %s\n", blocksize, curpos, path); - smbc_close(remotehandle); close(localhandle); + smbc_close(remotehandle); + if (localhandle != STDOUT_FILENO) close(localhandle); free(readbuf); return 0; } @@ -387,7 +394,8 @@ int smb_download_file(const char *base, const char *name, int recursive, int res if(write(localhandle, readbuf, bytesread) < 0) { fprintf(stderr, "Can't write %d bytes to local file %s at offset "OFF_T_FORMAT"\n", bytesread, path, curpos); free(readbuf); - smbc_close(remotehandle); close(localhandle); + smbc_close(remotehandle); + if (localhandle != STDOUT_FILENO) close(localhandle); return 0; } @@ -413,7 +421,7 @@ int smb_download_file(const char *base, const char *name, int recursive, int res fputc('\n', stderr); } - if(keep_permissions) { + if(keep_permissions && !send_stdout) { if(fchmod(localhandle, remotestat.st_mode) < 0) { fprintf(stderr, "Unable to change mode of local file %s to %o\n", path, remotestat.st_mode); smbc_close(remotehandle); @@ -421,8 +429,9 @@ int smb_download_file(const char *base, const char *name, int recursive, int res return 0; } } + smbc_close(remotehandle); - close(localhandle); + if (localhandle != STDOUT_FILENO) close(localhandle); return 1; } @@ -514,6 +523,7 @@ int main(int argc, const char **argv) {"nonprompt", 'n', POPT_ARG_NONE, &nonprompt, 'n', "Don't ask anything (non-interactive)" }, {"debuglevel", 'd', POPT_ARG_INT, &debuglevel, 'd', "Debuglevel to use" }, {"outputfile", 'o', POPT_ARG_STRING, &outputfile, 'o', "Write downloaded data to specified file" }, + {"stdout", 'O', POPT_ARG_NONE, &send_stdout, 'O', "Write data to stdout" }, {"dots", 'D', POPT_ARG_NONE, &dots, 'D', "Show dots as progress indication" }, {"quiet", 'q', POPT_ARG_NONE, &quiet, 'q', "Be quiet" }, {"verbose", 'v', POPT_ARG_NONE, &verbose, 'v', "Be verbose" }, @@ -549,8 +559,13 @@ int main(int argc, const char **argv) } } - if(outputfile && recursive) { - fprintf(stderr, "The -o and -R options can not be used together.\n"); + if((send_stdout || outputfile) && recursive) { + fprintf(stderr, "The -o or -O and -R options can not be used together.\n"); + return 1; + } + + if(outputfile && send_stdout) { + fprintf(stderr, "The -o and -O options cannot be used together.\n"); return 1; } -- cgit From 2aaba6696cca6a0579ff301b3d0e31efc041efb3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 Mar 2004 17:39:59 +0000 Subject: fix compiler warning (This used to be commit 7153cbf8cbb07d4e7a9dc9adc9e0a40c57a6e305) --- source3/printing/printing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 1efd932749..ad11108a5a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -658,7 +658,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void struct traverse_struct *ts = (struct traverse_struct *)state; struct printjob pjob; uint32 jobid; - int i; + int i = 0; if ( key.dsize != sizeof(jobid) ) return 0; -- cgit From 21c4e30fccbf7207ccad28fb188839e0635290ba Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 Mar 2004 18:37:32 +0000 Subject: BUG 488: fix the 'show client in col 1' button and corrctely enumerate active connections (This used to be commit f0e454f6eb3ed25c3210f288d48044b3eed9d129) --- source3/web/statuspage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c index 9ce9c05b19..3d70796830 100644 --- a/source3/web/statuspage.c +++ b/source3/web/statuspage.c @@ -177,7 +177,7 @@ static int traverse_fn2(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st memcpy(&crec, dbuf.dptr, sizeof(crec)); - if (crec.cnum != -1 || !process_exists(crec.pid) || (crec.pid == smbd_pid)) + if (crec.cnum == -1 || !process_exists(crec.pid) || (crec.pid == smbd_pid)) return 0; addPid2Machine (crec.pid, crec.machine); -- cgit From 443865396b9f7b98123cb81104fa0604ec4ca202 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Mar 2004 22:32:43 +0000 Subject: Several mb tidyups - getting ready to address the XXX_sub function. Jeremy. (This used to be commit 13edba472a0a5eb56586458a2432d53f495d0129) --- source3/smbd/filename.c | 14 ++-- source3/smbd/service.c | 180 +++++++++++++++++++++++------------------------- source3/smbd/trans2.c | 6 +- source3/smbd/vfs.c | 13 ++-- 4 files changed, 105 insertions(+), 108 deletions(-) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 8300674d61..805af9c494 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. filename handling routines Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Jeremy Allison 1999-200 + Copyright (C) Jeremy Allison 1999-2004 Copyright (C) Ying Chen 2000 This program is free software; you can redistribute it and/or modify @@ -392,9 +392,10 @@ BOOL check_name(pstring name,connection_struct *conn) errno = 0; if (IS_VETO_PATH(conn, name)) { - if(strcmp(name, ".") && strcmp(name, "..")) { + /* Is it not dot or dot dot. */ + if (!((name[0] == '.') && (!name[1] || (name[1] == '.' && !name[2])))) { DEBUG(5,("file path name %s vetoed\n",name)); - return(0); + return False; } } @@ -412,7 +413,7 @@ BOOL check_name(pstring name,connection_struct *conn) if ( (SMB_VFS_LSTAT(conn,name,&statbuf) != -1) && (S_ISLNK(statbuf.st_mode)) ) { DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name)); - ret=0; + ret = False; } } #endif @@ -464,8 +465,11 @@ static BOOL scan_directory(const char *path, char *name, size_t maxlength, /* now scan for matching names */ while ((dname = ReadDirName(cur_dir))) { - if (*dname == '.' && (strequal(dname,".") || strequal(dname,".."))) + + /* Is it dot or dot dot. */ + if ((dname[0] == '.') && (!dname[1] || (dname[1] == '.' && !dname[2]))) { continue; + } /* * At this point dname is the unmangled name. diff --git a/source3/smbd/service.c b/source3/smbd/service.c index caa2872f04..f39f5bfd59 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -112,105 +112,96 @@ int add_home_service(const char *service, const char *username, const char *home /** - * Find a service entry. service is always in dos codepage. + * Find a service entry. * * @param service is modified (to canonical form??) **/ + int find_service(fstring service) { - int iService; - - all_string_sub(service,"\\","/",0); - - iService = lp_servicenumber(service); - - /* now handle the special case of a home directory */ - if (iService < 0) - { - char *phome_dir = get_user_home_dir(service); - - if(!phome_dir) - { - /* - * Try mapping the servicename, it may - * be a Windows to unix mapped user name. - */ - if(map_username(service)) - phome_dir = get_user_home_dir(service); - } - - DEBUG(3,("checking for home directory %s gave %s\n",service, - phome_dir?phome_dir:"(NULL)")); - - iService = add_home_service(service,service /* 'username' */, phome_dir); - } - - /* If we still don't have a service, attempt to add it as a printer. */ - if (iService < 0) - { - int iPrinterService; - - if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) - { - char *pszTemp; - - DEBUG(3,("checking whether %s is a valid printer name...\n", service)); - pszTemp = lp_printcapname(); - if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp)) - { - DEBUG(3,("%s is a valid printer name\n", service)); - DEBUG(3,("adding %s as a printer service\n", service)); - lp_add_printer(service, iPrinterService); - iService = lp_servicenumber(service); - if (iService < 0) - DEBUG(0,("failed to add %s as a printer service!\n", service)); - } - else - DEBUG(3,("%s is not a valid printer name\n", service)); - } - } - - /* Check for default vfs service? Unsure whether to implement this */ - if (iService < 0) - { - } - - /* just possibly it's a default service? */ - if (iService < 0) - { - char *pdefservice = lp_defaultservice(); - if (pdefservice && *pdefservice && - !strequal(pdefservice,service) && - !strstr(service,"..")) - { - /* - * We need to do a local copy here as lp_defaultservice() - * returns one of the rotating lp_string buffers that - * could get overwritten by the recursive find_service() call - * below. Fix from Josef Hinteregger . - */ - pstring defservice; - pstrcpy(defservice, pdefservice); - iService = find_service(defservice); - if (iService >= 0) - { - all_string_sub(service, "_","/",0); - iService = lp_add_service(service, iService); - } - } - } - - if (iService >= 0) - if (!VALID_SNUM(iService)) - { - DEBUG(0,("Invalid snum %d for %s\n",iService, service)); - iService = -1; - } - - if (iService < 0) - DEBUG(3,("find_service() failed to find service %s\n", service)); - - return (iService); + int iService; + + all_string_sub(service,"\\","/",0); + + iService = lp_servicenumber(service); + + /* now handle the special case of a home directory */ + if (iService < 0) { + char *phome_dir = get_user_home_dir(service); + + if(!phome_dir) { + /* + * Try mapping the servicename, it may + * be a Windows to unix mapped user name. + */ + if(map_username(service)) + phome_dir = get_user_home_dir(service); + } + + DEBUG(3,("checking for home directory %s gave %s\n",service, + phome_dir?phome_dir:"(NULL)")); + + iService = add_home_service(service,service /* 'username' */, phome_dir); + } + + /* If we still don't have a service, attempt to add it as a printer. */ + if (iService < 0) { + int iPrinterService; + + if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) { + char *pszTemp; + + DEBUG(3,("checking whether %s is a valid printer name...\n", service)); + pszTemp = lp_printcapname(); + if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp)) { + DEBUG(3,("%s is a valid printer name\n", service)); + DEBUG(3,("adding %s as a printer service\n", service)); + lp_add_printer(service, iPrinterService); + iService = lp_servicenumber(service); + if (iService < 0) { + DEBUG(0,("failed to add %s as a printer service!\n", service)); + } + } else { + DEBUG(3,("%s is not a valid printer name\n", service)); + } + } + } + + /* Check for default vfs service? Unsure whether to implement this */ + if (iService < 0) { + } + + /* just possibly it's a default service? */ + if (iService < 0) { + char *pdefservice = lp_defaultservice(); + if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr(service,"..")) { + /* + * We need to do a local copy here as lp_defaultservice() + * returns one of the rotating lp_string buffers that + * could get overwritten by the recursive find_service() call + * below. Fix from Josef Hinteregger . + */ + pstring defservice; + pstrcpy(defservice, pdefservice); + iService = find_service(defservice); + if (iService >= 0) { + all_string_sub(service, "_","/",0); + iService = lp_add_service(service, iService); + } + } + } + + if (iService >= 0) { + if (!VALID_SNUM(iService)) { + DEBUG(0,("Invalid snum %d for %s\n",iService, service)); + iService = -1; + } + } + + if (iService < 0) + DEBUG(3,("find_service() failed to find service %s\n", service)); + + return (iService); } @@ -218,6 +209,7 @@ int find_service(fstring service) do some basic sainity checks on the share. This function modifies dev, ecode. ****************************************************************************/ + static NTSTATUS share_sanity_checks(int snum, fstring dev) { diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index e2df517f40..38fed4beae 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -249,6 +249,9 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i open_size = IVAL(params,14); pname = ¶ms[28]; + if (IS_IPC(conn)) + return(ERROR_DOS(ERRSRV,ERRaccess)); + srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); @@ -257,9 +260,6 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n", fname,open_mode, open_attr, open_ofun, open_size)); - if (IS_IPC(conn)) - return(ERROR_DOS(ERRSRV,ERRaccess)); - /* XXXX we need to handle passed times, sattr and flags */ unix_convert(fname,conn,0,&bad_path,&sbuf); diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 284e24e7b1..4f3234775a 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -863,8 +863,8 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir) DEBUG(3,("reduce_name [%s] [%s]\n",s,dir)); - /* remove any double slashes */ - all_string_sub(s,"//","/",0); + /* We know there are no double slashes as this comes from srvstr_get_path(). + and has gone through check_path_syntax(). JRA */ pstrcpy(base_name,s); p = strrchr_m(base_name,'/'); @@ -915,17 +915,19 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir) { size_t l = strlen(dir2); - if (dir2[l-1] == '/') + char *last_slash = strrchr_m(dir2, '/'); + + if (last_slash && (last_slash[1] == '\0')) l--; if (strncmp(newname,dir2,l) != 0) { vfs_ChDir(conn,wd); - DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,(int)l)); + DEBUG(2,("Bad access attempt: s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,(int)l)); return(False); } if (!readlink_check(conn, dir, newname)) { - DEBUG(2, ("Bad access attemt? %s is a symlink outside the share path", s)); + DEBUG(2, ("Bad access attemt: %s is a symlink outside the share path", s)); return(False); } @@ -947,4 +949,3 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir) return(True); #endif } - -- cgit From 2a3c286cdc620ecdc34ecee4e8a3d185a5ed3f61 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 6 Mar 2004 23:52:54 +0000 Subject: tdbdump doesn't need to #include Bugzilla #1154. (This used to be commit 311bbf41ec50d5caf4388cb4745173739744a049) --- source3/tdb/tdbdump.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/tdb/tdbdump.c b/source3/tdb/tdbdump.c index 9c1dc2761b..d2530f9f54 100644 --- a/source3/tdb/tdbdump.c +++ b/source3/tdb/tdbdump.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include -- cgit From a843787637292e115cc1bd66475e6d4d686f9bc0 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 7 Mar 2004 00:34:49 +0000 Subject: Enclose use of fchown() with guards. Bugzilla #1155. (This used to be commit 92f6895dd11189ce966b8b5a3f9ace54f478a375) --- source3/smbd/vfs-wrap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c index 4f2d82734f..5393dfc755 100644 --- a/source3/smbd/vfs-wrap.c +++ b/source3/smbd/vfs-wrap.c @@ -359,7 +359,11 @@ static int copy_reg(const char *source, const char *dest) * But root probably wants to know, e.g. if NFS disallows it. */ +#ifdef HAVE_FCHOWN if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) +#else + if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) +#endif goto err; /* -- cgit From 420a55949dd70d334b54583efde189ac23ca77fb Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 7 Mar 2004 01:14:35 +0000 Subject: Fix typo. (This used to be commit 7798a52d82c46759635e90a7e48ddad4ce48b763) --- source3/lib/smbldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index fcebccc58a..3bd8b12f2d 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -103,7 +103,7 @@ ATTRIB_MAP_ENTRY attrib_map_v30[] = { { LDAP_ATTR_LIST_END, NULL } }; -/* attributes used for alalocating RIDs */ +/* attributes used for allocating RIDs */ ATTRIB_MAP_ENTRY dominfo_attr_list[] = { { LDAP_ATTR_DOMAIN, "sambaDomainName" }, -- cgit From c1e4d37bdddb79e94b65890279bf13b53aacc36d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 7 Mar 2004 08:17:09 +0000 Subject: This might not be used a lot and might not survive for long, but at least it should work as expected :-) Fix wb_delgrpmember. Volker (This used to be commit 2a2b4a159a973678b7279a8d91060c7c27aa22e8) --- source3/nsswitch/wbinfo.c | 2 +- source3/nsswitch/winbindd_acct.c | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 4f6cc4225a..772332ee59 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -1179,7 +1179,7 @@ int main(int argc, char **argv) break; case 'O': if ( !wbinfo_remove_user_from_group(string_arg) ) { - d_printf("Could not remove user kfrom group\n"); + d_printf("Could not remove user from group\n"); goto done; } break; diff --git a/source3/nsswitch/winbindd_acct.c b/source3/nsswitch/winbindd_acct.c index 2f94a2efd0..be3f1405e4 100644 --- a/source3/nsswitch/winbindd_acct.c +++ b/source3/nsswitch/winbindd_acct.c @@ -371,7 +371,7 @@ static WINBINDD_GR* string2group( char *string ) if ( num_gr_members ) { fstring buffer; - gr_members = (char**)smb_xmalloc(sizeof(char*)*num_gr_members+1); + gr_members = (char**)smb_xmalloc(sizeof(char*)*(num_gr_members+1)); i = 0; while ( next_token(&str, buffer, ",", sizeof(buffer)) && inum_gr_mem && !found; i++ ) { - if ( StrCaseCmp( grp->gr_mem[i], user ) == 0 ) + for ( i=0; inum_gr_mem; i++ ) { + if ( StrCaseCmp( grp->gr_mem[i], user ) == 0 ) { found = True; + break; + } } if ( !found ) @@ -826,8 +828,10 @@ static BOOL wb_delgrpmember( WINBINDD_GR *grp, const char *user ) /* still some remaining members */ if ( grp->num_gr_mem > 1 ) { - memmove( grp->gr_mem[i], grp->gr_mem[i+1], sizeof(char*)*(grp->num_gr_mem-(i+1)) ); + SAFE_FREE(grp->gr_mem[i]); grp->num_gr_mem--; + grp->gr_mem[i] = grp->gr_mem[grp->num_gr_mem]; + grp->gr_mem[grp->num_gr_mem] = NULL; } else { /* last one */ free_winbindd_gr( grp ); @@ -1237,7 +1241,7 @@ enum winbindd_result winbindd_remove_user_from_group(struct winbindd_cli_state * group = state->request.data.acct_mgt.groupname; user = state->request.data.acct_mgt.username; - DEBUG(3, ("[%5lu]: remove_user_to_group: delete %s from %s\n", (unsigned long)state->pid, + DEBUG(3, ("[%5lu]: remove_user_from_group: delete %s from %s\n", (unsigned long)state->pid, user, group)); /* don't worry about checking the username since we're removing it anyways */ @@ -1245,7 +1249,7 @@ enum winbindd_result winbindd_remove_user_from_group(struct winbindd_cli_state * /* make sure it is a valid group */ if ( !(grp = wb_getgrnam( group )) ) { - DEBUG(4,("winbindd_remove_user_to_group: Cannot remove a user to a non-extistent group\n")); + DEBUG(4,("winbindd_remove_user_from_group: Cannot remove a user from a non-extistent group\n")); return WINBINDD_ERROR; } -- cgit From cd1be774adc1a2509d93e65e48088b5351c99a13 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 7 Mar 2004 08:23:06 +0000 Subject: Get us a little closer to Windows LSA semantics. A windows DC does not reply to DCNAME\\Administrator, only to DOMAIN\\Administrator. Fix that. Without winbind we are wrong as domain members, we should forward the request DOMAIN\\Username to the DC on behalf of the asking client. Winbind fixes that nicely. Volker (This used to be commit c39f698dde98de9b6be40a6c81e669dcd7696b3a) --- source3/passdb/lookup_sid.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index 425c9b87f1..83d2cd28ac 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -36,16 +36,7 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N /* If we are looking up a domain user, make sure it is for the local machine only */ - if (strequal(global_myname(), domain)) { - local_lookup = True; - } else if (lp_server_role() == ROLE_DOMAIN_PDC || - lp_server_role() == ROLE_DOMAIN_BDC) { - if (strequal(domain, lp_workgroup())) { - local_lookup = True; - } - } - - if (local_lookup) { + if (strequal(domain, get_global_sam_name())) { if (local_lookup_name(name, psid, name_type)) { DEBUG(10, ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n", -- cgit From 9c15b5b0ec08bd13a7f3e888482165207926e7f9 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 8 Mar 2004 09:52:17 +0000 Subject: 2 fixes to enhance readability of source code and debug messages 1 fix for a memleak (This used to be commit 9f3b0295fe7bd6c0c3a6061e5d00e7b88f702b21) --- source3/lib/privileges.c | 2 +- source3/passdb/passdb.c | 2 ++ source3/smbd/sec_ctx.c | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c index 4bcf5e3b36..a3b85372c7 100644 --- a/source3/lib/privileges.c +++ b/source3/lib/privileges.c @@ -372,7 +372,7 @@ NTSTATUS dup_priv_set(PRIVILEGE_SET *new_priv_set, PRIVILEGE_SET *priv_set) LUID_ATTR *old_set; int i; - if (!new_priv_set || !priv_set) + if (new_priv_set == NULL || priv_set == NULL) return NT_STATUS_INVALID_PARAMETER; /* special case if there are no privileges in the list */ diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 7c9376e045..273428dacf 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1892,6 +1892,8 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) done: + SAFE_FREE(lm_pw_ptr); + SAFE_FREE(nt_pw_ptr); SAFE_FREE(username); SAFE_FREE(domain); SAFE_FREE(nt_username); diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c index 9244f34394..97fe2dfaee 100644 --- a/source3/smbd/sec_ctx.c +++ b/source3/smbd/sec_ctx.c @@ -258,7 +258,7 @@ BOOL push_sec_ctx(void) ctx_p->token = dup_nt_token(sec_ctx_stack[sec_ctx_stack_ndx-1].token); if (! ctx_p->token) { - DEBUG(0, ("Out of memory in push_sec_ctx()\n")); + DEBUG(0, ("Out of memory on dup_nt_token() in push_sec_ctx()\n")); return False; } @@ -266,7 +266,7 @@ BOOL push_sec_ctx(void) if (ctx_p->ngroups != 0) { if (!(ctx_p->groups = malloc(ctx_p->ngroups * sizeof(gid_t)))) { - DEBUG(0, ("Out of memory in push_sec_ctx()\n")); + DEBUG(0, ("Out of memory on malloc() in push_sec_ctx()\n")); delete_nt_token(&ctx_p->token); return False; } @@ -278,7 +278,7 @@ BOOL push_sec_ctx(void) init_privilege(&ctx_p->privs); if (! NT_STATUS_IS_OK(dup_priv_set(ctx_p->privs, sec_ctx_stack[sec_ctx_stack_ndx-1].privs))) { - DEBUG(0, ("Out of memory in push_sec_ctx()\n")); + DEBUG(0, ("Out of memory on dup_priv_set() in push_sec_ctx()\n")); delete_nt_token(&ctx_p->token); destroy_privilege(&ctx_p->privs); return False; -- cgit From 22115af66114cfc3641576acfa998e12bab74e33 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 8 Mar 2004 10:41:05 +0000 Subject: Do some checks about data passed to this function (This used to be commit 77142a1ca6853fcae3b806830d077f6f84bebd6d) --- source3/lib/privileges.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c index a3b85372c7..cd888b6513 100644 --- a/source3/lib/privileges.c +++ b/source3/lib/privileges.c @@ -170,6 +170,9 @@ void reset_privilege(PRIVILEGE_SET *priv_set) void destroy_privilege(PRIVILEGE_SET **priv_set) { + if (priv_set == NULL || *priv_set == NULL) + return; + reset_privilege(*priv_set); if (!((*priv_set)->ext_ctx)) /* mem_ctx is local, destroy it */ -- cgit From 2337d3e1a543724083d11897de296b91200906ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 8 Mar 2004 21:54:56 +0000 Subject: Fix assumption about following directory sep in check_path_syntax(). We need to try and convert 1 byte, then 2 bytes if that fails. Fixes bug reported by Simo. Jeremy. (This used to be commit 0f84801ff3ed5acfcf8e0c4a825f90b9b4823da5) --- source3/smbd/reply.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c0d5234f47..1ff969493e 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -114,14 +114,20 @@ static NTSTATUS check_path_syntax(pstring destname, const pstring srcname) /* * Potential mb char with second char a directory separator. * All the encodings we care about are 2 byte only, so do a - * conversion to unicode. If the 2 byte char won't convert then - * it's probably a one byte char with a real directory separator - * following, so only copy one byte. If it will convert then - * copy both bytes. + * conversion to unicode. If the one byte char converts then + * it really is a directory separator following. Otherwise if + * the two byte character converts (and it should or our assumption + * about character sets is broken and we panic) then copy both + * bytes as it's a MB character, not a directory separator. */ + uint16 ucs2_val; - if (convert_string(CH_UNIX, CH_UCS2, s, 2, &ucs2_val, 2) == 2) { + if (convert_string(CH_UNIX, CH_UCS2, s, 1, &ucs2_val, 2) == 2) { + ; + } else if (convert_string(CH_UNIX, CH_UCS2, s, 2, &ucs2_val, 2) == 2) { *d++ = *s++; + } else { + smb_panic("check_path_syntax: directory separator assumptions invalid !\n"); } } /* Just copy the char (or the second byte of the mb char). */ -- cgit From fe5801d065a140dc79bec3ff4c41024470ab5cfd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Mar 2004 00:17:16 +0000 Subject: Added strstr_m() function. Use in all places where we might run into mb (should fix the mb service name problem, can't remember the bugid). Jeremy. (This used to be commit 93c2d50f1adbf257c0c0185b420a1d73d56be2f9) --- source3/lib/util.c | 4 +-- source3/lib/util_str.c | 78 +++++++++++++++++++++++++++++++++++++++++--- source3/printing/lpq_parse.c | 6 ++-- source3/smbd/chgpasswd.c | 2 +- source3/smbd/service.c | 2 +- source3/utils/testparm.c | 2 +- 6 files changed, 82 insertions(+), 12 deletions(-) diff --git a/source3/lib/util.c b/source3/lib/util.c index f169a3103e..3a8d627ee9 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -551,7 +551,7 @@ void dos_clean_name(char *s) /* remove any double slashes */ all_string_sub(s, "\\\\", "\\", 0); - while ((p = strstr(s,"\\..\\")) != NULL) { + while ((p = strstr_m(s,"\\..\\")) != NULL) { pstring s1; *p = 0; @@ -589,7 +589,7 @@ void unix_clean_name(char *s) pstrcpy(s,"./"); } - while ((p = strstr(s,"/../")) != NULL) { + while ((p = strstr_m(s,"/../")) != NULL) { pstring s1; *p = 0; diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 71c8d56e40..cad0df48a4 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -919,7 +919,7 @@ void string_sub(char *s,const char *pattern, const char *insert, size_t len) if (len == 0) len = ls + 1; /* len is number of *bytes* */ - while (lp <= ls && (p = strstr(s,pattern))) { + while (lp <= ls && (p = strstr_m(s,pattern))) { if (ls + (li-lp) >= len) { DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), @@ -1004,7 +1004,7 @@ char *realloc_string_sub(char *string, const char *pattern, const char *insert) } } - while ((p = strstr(s,pattern))) { + while ((p = strstr_m(s,pattern))) { if (ld > 0) { int offset = PTR_DIFF(s,string); char *t = Realloc(string, ls + ld + 1); @@ -1052,7 +1052,7 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len) if (len == 0) len = ls + 1; /* len is number of *bytes* */ - while (lp <= ls && (p = strstr(s,pattern))) { + while (lp <= ls && (p = strstr_m(s,pattern))) { if (ls + (li-lp) >= len) { DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), @@ -1294,6 +1294,76 @@ char *strnrchr_m(const char *s, char c, unsigned int n) return (char *)(s+strlen(s2)); } +/*********************************************************************** + strstr_m - We convert via ucs2 for now. +***********************************************************************/ + +char *strstr_m(const char *src, const char *findstr) +{ + smb_ucs2_t *p; + smb_ucs2_t *src_w, *find_w; + const char *s; + char *s2; + char *retp; + + /* Samba does single character findstr calls a *lot*. */ + if (findstr[1] == '\0') + return strchr_m(src, *findstr); + + /* We optimise for the ascii case, knowing that all our + supported multi-byte character sets are ascii-compatible + (ie. they match for the first 128 chars) */ + + for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) { + if (*s == *findstr) { + if (strcmp(s, findstr) == 0) { + return (char *)s; + } + } + } + + if (!*s) + return NULL; + +#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS + /* With compose characters we must restart from the beginning. JRA. */ + s = src; +#endif + + if (push_ucs2_allocate(&src_w, src) == (size_t)-1) { + DEBUG(0,("strstr_m: src malloc fail\n")); + return NULL; + } + + if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) { + SAFE_FREE(src_w); + DEBUG(0,("strstr_m: find malloc fail\n")); + return NULL; + } + + for (p = src_w; (p = strchr_w(p, *find_w)) != NULL; p++) { + if (strcmp_w(p, find_w) == 0) + break; + } + if (!p) { + SAFE_FREE(src_w); + SAFE_FREE(find_w); + return NULL; + } + *p = 0; + if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) { + SAFE_FREE(src_w); + SAFE_FREE(find_w); + DEBUG(0,("strstr_m: dest malloc fail\n")); + return NULL; + } + retp = (char *)(s+strlen(s2)); + SAFE_FREE(src_w); + SAFE_FREE(find_w); + SAFE_FREE(s2); + return retp; +} + /** Convert a string to lower case. **/ @@ -1624,7 +1694,7 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert) s = *list; ls = (ssize_t)strlen(s); - while ((p = strstr(s, pattern))) { + while ((p = strstr_m(s, pattern))) { t = *list; d = p -t; if (ld) { diff --git a/source3/printing/lpq_parse.c b/source3/printing/lpq_parse.c index 111617e3ae..b7e41964f1 100644 --- a/source3/printing/lpq_parse.c +++ b/source3/printing/lpq_parse.c @@ -989,21 +989,21 @@ BOOL parse_lpq_entry(int snum,char *line, switch (status->status) { case LPSTAT_OK: for (i=0; stat0_strings[i]; i++) - if (strstr(line,stat0_strings[i])) { + if (strstr_m(line,stat0_strings[i])) { fstrcpy(status->message,line); status->status=LPSTAT_OK; return ret; } case LPSTAT_STOPPED: for (i=0; stat1_strings[i]; i++) - if (strstr(line,stat1_strings[i])) { + if (strstr_m(line,stat1_strings[i])) { fstrcpy(status->message,line); status->status=LPSTAT_STOPPED; return ret; } case LPSTAT_ERROR: for (i=0; stat2_strings[i]; i++) - if (strstr(line,stat2_strings[i])) { + if (strstr_m(line,stat2_strings[i])) { fstrcpy(status->message,line); status->status=LPSTAT_ERROR; return ret; diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 8e4df1a464..4192cc3a23 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -542,7 +542,7 @@ BOOL chgpasswd(const char *name, const struct passwd *pass, if (as_root) { /* The password program *must* contain the user name to work. Fail if not. */ - if (strstr(passwordprogram, "%u") == NULL) { + if (strstr_m(passwordprogram, "%u") == NULL) { DEBUG(0,("chgpasswd: Running as root the 'passwd program' parameter *MUST* contain \ the string %%u, and the given string %s does not.\n", passwordprogram )); return False; diff --git a/source3/smbd/service.c b/source3/smbd/service.c index f39f5bfd59..adbed67b33 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -174,7 +174,7 @@ int find_service(fstring service) /* just possibly it's a default service? */ if (iService < 0) { char *pdefservice = lp_defaultservice(); - if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr(service,"..")) { + if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr_m(service,"..")) { /* * We need to do a local copy here as lp_defaultservice() * returns one of the rotating lp_string buffers that diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c index a74c2eaa97..9db6d538d2 100644 --- a/source3/utils/testparm.c +++ b/source3/utils/testparm.c @@ -150,7 +150,7 @@ parameter.\n"); */ if(lp_encrypted_passwords()) { - if(strstr( lp_passwd_chat(), "%o")!=NULL) { + if(strstr_m( lp_passwd_chat(), "%o")!=NULL) { fprintf(stderr, "ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_passwd_chat() ); ret = 1; -- cgit From 6100210db96e8647c33b4bf67458ce55f28a53e1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 9 Mar 2004 11:42:58 +0000 Subject: Merge fixes and tests for jra's broken strstr_m() function from 3.0 STF rules! (Pity we don't use it for more stuff) Andrew Bartlett (This used to be commit a9363b45b0ef652a5fd621915fafb97ada0c7d5e) --- source3/Makefile.in | 5 ++++- source3/lib/util_str.c | 26 +++++++++++++++++++------- source3/stf/strings.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ source3/torture/t_strstr.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 source3/torture/t_strstr.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 5792b00264..0008a85f75 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1218,6 +1218,9 @@ bin/tdbdump@EXEEXT@: $(TDBDUMP_OBJ) bin/.dummy bin/t_strcmp@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o $(CC) $(FLAGS) -o $@ $(LIBS) torture/t_strcmp.o -L ./bin -lbigballofmud +bin/t_strstr@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strstr.o + $(CC) $(FLAGS) -o $@ $(LIBS) torture/t_strstr.o -L ./bin -lbigballofmud + bin/t_stringoverflow@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_stringoverflow.o $(CC) $(FLAGS) -o $@ torture/t_stringoverflow.o -L./bin -lbigballofmud @@ -1511,4 +1514,4 @@ check: check-programs # These are called by the test suite and need to be built before # running it. For the time being we don't build all of BIN_PROGS, # because they're not all needed. -check-programs: bin/t_strcmp bin/t_push_ucs2 bin/smbcontrol bin/t_snprintf +check-programs: bin/t_strcmp bin/t_strstr bin/t_push_ucs2 bin/smbcontrol bin/t_snprintf diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index cad0df48a4..b8cf052862 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1306,6 +1306,14 @@ char *strstr_m(const char *src, const char *findstr) char *s2; char *retp; + size_t findstr_len = 0; + size_t find_w_len; + + /* for correctness */ + if (!findstr[0]) { + return src; + } + /* Samba does single character findstr calls a *lot*. */ if (findstr[1] == '\0') return strchr_m(src, *findstr); @@ -1316,7 +1324,10 @@ char *strstr_m(const char *src, const char *findstr) for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) { if (*s == *findstr) { - if (strcmp(s, findstr) == 0) { + if (!findstr_len) + findstr_len = strlen(findstr); + + if (strncmp(s, findstr, findstr_len) == 0) { return (char *)s; } } @@ -1325,7 +1336,9 @@ char *strstr_m(const char *src, const char *findstr) if (!*s) return NULL; -#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS +#if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */ + /* 'make check' fails unless we do this */ + /* With compose characters we must restart from the beginning. JRA. */ s = src; #endif @@ -1340,16 +1353,15 @@ char *strstr_m(const char *src, const char *findstr) DEBUG(0,("strstr_m: find malloc fail\n")); return NULL; } - - for (p = src_w; (p = strchr_w(p, *find_w)) != NULL; p++) { - if (strcmp_w(p, find_w) == 0) - break; - } + + p = strstr_w(src_w, find_w); + if (!p) { SAFE_FREE(src_w); SAFE_FREE(find_w); return NULL; } + *p = 0; if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) { SAFE_FREE(src_w); diff --git a/source3/stf/strings.py b/source3/stf/strings.py index 328849b1ce..86f7acdeb4 100755 --- a/source3/stf/strings.py +++ b/source3/stf/strings.py @@ -94,8 +94,52 @@ class StrCaseCmp(comfychair.TestCase): for a, b, expect in cases: self.run_strcmp(a, b, expect) +class strstr_m(comfychair.TestCase): + """String comparisons in simple ASCII""" + def run_strstr(self, a, b, expect): + out, err = self.runcmd('t_strstr \"%s\" \"%s\"' % (a.encode('utf-8'), b.encode('utf-8'))) + if (out != (expect + '\n').encode('utf-8')): + self.fail("comparison failed:\n" + " a=%s\n" + " b=%s\n" + " expected=%s\n" + " result=%s\n" % (`a`, `b`, `expect+'\n'`, `out`)) + + def runtest(self): + # A, B, strstr_m(A, B) + cases = [('hello', 'hello', 'hello'), + ('hello', 'goodbye', '(null)'), + ('goodbye', 'hello', '(null)'), + ('hell', 'hello', '(null)'), + ('hello', 'hell', 'hello'), + ('', '', ''), + ('a', '', 'a'), + ('', 'a', '(null)'), + ('a', 'A', '(null)'), + ('aa', 'aA', '(null)'), + ('Aa', 'aa', '(null)'), + ('%v foo', '%v', '%v foo'), + ('foo %v foo', '%v', '%v foo'), + ('foo %v', '%v', '%v'), + ('longstring ' * 100, 'longstring ' * 99, 'longstring ' * 100), + ('longstring ' * 99, 'longstring ' * 100, '(null)'), + ('longstring a' * 99, 'longstring ' * 100 + 'a', '(null)'), + ('longstring ' * 100 + 'a', 'longstring ' * 100, 'longstring ' * 100 + 'a'), + (KATAKANA_LETTER_A, KATAKANA_LETTER_A + 'bcd', '(null)'), + (KATAKANA_LETTER_A + 'bcde', KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcde'), + ('d'+KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcd'), + ('d'+KATAKANA_LETTER_A + 'bd', KATAKANA_LETTER_A + 'bcd', '(null)'), + + ('e'+KATAKANA_LETTER_A + 'bcdf', KATAKANA_LETTER_A + 'bcd', KATAKANA_LETTER_A + 'bcdf'), + (KATAKANA_LETTER_A, KATAKANA_LETTER_A + 'bcd', '(null)'), + (KATAKANA_LETTER_A*3, 'a', '(null)'), + ] + for a, b, expect in cases: + self.run_strstr(a, b, expect) + # Define the tests exported by this module tests = [StrCaseCmp, + strstr_m, PushUCS2_Tests] # Handle execution of this file as a main program diff --git a/source3/torture/t_strstr.c b/source3/torture/t_strstr.c new file mode 100644 index 0000000000..25709526fe --- /dev/null +++ b/source3/torture/t_strstr.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2003 by Martin Pool + * + * Test harness for strstr_m + */ + +#include "includes.h" + +int main(int argc, char *argv[]) +{ + int i; + int iters = 1; + + char *ret; + + /* Needed to initialize character set */ + lp_load("/dev/null", True, False, False); + + if (argc < 3) { + fprintf(stderr, "usage: %s STRING1 STRING2 [ITERS]\n" + "Compares two strings, prints the results of strstr_m\n", + argv[0]); + return 2; + } + if (argc >= 4) + iters = atoi(argv[3]); + + for (i = 0; i < iters; i++) { + ret = strstr_m(argv[1], argv[2]); + } + + printf("%s\n", ret); + + return 0; +} -- cgit From 4b683427acea8196cee1c8249ac5f25c98fb568e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 9 Mar 2004 12:37:05 +0000 Subject: Commit to HEAD the updates to smb signing code that I was propsing for 3.0. This code implements 'opportunistic signing' in our client (when the server supports it, we will use it), and correct downgrading on both the client and server for the 'enabled' (rather than required) signing level. This means that we can actually set 'server signing = yes' and not have the world fall apart. We had a number of bugs in that code, and it certainly looks like most of the testing was with the 'requried' setting. While the changes are reasonable, I'm putting this into HEAD rather than 3.0 for the timebeing. SMB signing, like NTLMSSP, tends to have gotchas in it :-) (I also need to give it a workout with more than smbclient before I move it across). Andrew Bartlett (This used to be commit 6bad895462cf076a7e917c909e2a461d1b360bf1) --- source3/include/smb.h | 3 +- source3/lib/util_sock.c | 2 +- source3/libsmb/cliconnect.c | 23 +++++---- source3/libsmb/clientgen.c | 2 +- source3/libsmb/smb_signing.c | 120 +++++++++++++++++++++++++++---------------- source3/smbd/password.c | 2 +- source3/smbd/sesssetup.c | 11 ++-- 7 files changed, 101 insertions(+), 62 deletions(-) diff --git a/source3/include/smb.h b/source3/include/smb.h index 298944a0b1..60be41b12e 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1650,7 +1650,7 @@ struct ip_service { typedef struct smb_sign_info { void (*sign_outgoing_message)(char *outbuf, struct smb_sign_info *si); - BOOL (*check_incoming_message)(char *inbuf, struct smb_sign_info *si); + BOOL (*check_incoming_message)(char *inbuf, struct smb_sign_info *si, BOOL expected_ok); void (*free_signing_context)(struct smb_sign_info *si); void *signing_context; @@ -1658,6 +1658,7 @@ typedef struct smb_sign_info { BOOL allow_smb_signing; BOOL doing_signing; BOOL mandatory_signing; + BOOL seen_valid; /* Have I ever seen a validly signed packet? */ } smb_sign_info; #endif /* _SMB_H */ diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index a275ddabb9..15ce883b09 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -596,7 +596,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) } /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(buffer)) { + if (!srv_check_sign_mac(buffer, True)) { DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); if (smb_read_error == 0) smb_read_error = READ_BAD_SIG; diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 84159e5d62..b5993cd1e6 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -325,7 +325,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - cli_simple_set_signing(cli, session_key, nt_response, 0); + cli_simple_set_signing(cli, session_key, nt_response); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -521,7 +521,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); #endif - cli_simple_set_signing(cli, session_key_krb5, null_blob, 0); + cli_simple_set_signing(cli, session_key_krb5, null_blob); blob2 = cli_session_setup_blob(cli, negTokenTarg); @@ -643,13 +643,16 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use fstrcpy(cli->server_domain, ntlmssp_state->server_domain); cli_set_session_key(cli, ntlmssp_state->session_key); - /* Using NTLMSSP session setup, signing on the net only starts - * after a successful authentication and the session key has - * been determined, but with a sequence number of 2. This - * assumes that NTLMSSP needs exactly 2 roundtrips, for any - * other SPNEGO mechanism it needs adapting. */ - - cli_simple_set_signing(cli, key, null_blob, 2); + if (cli_simple_set_signing(cli, key, null_blob)) { + + /* 'resign' the last message, so we get the right sequence numbers + for checking the first reply from the server */ + cli_calculate_sign_mac(cli); + + if (!cli_check_sign_mac(cli, True)) { + nt_status = NT_STATUS_ACCESS_DENIED; + } + } } /* we have a reference conter on ntlmssp_state, if we are signing @@ -1088,6 +1091,8 @@ BOOL cli_negprot(struct cli_state *cli) } cli->sign_info.negotiated_smb_signing = True; cli->sign_info.mandatory_signing = True; + } else if (cli->sign_info.allow_smb_signing && cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) { + cli->sign_info.negotiated_smb_signing = True; } } else if (cli->protocol >= PROTOCOL_LANMAN1) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0873700fc0..20a0483881 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -117,7 +117,7 @@ BOOL cli_receive_smb(struct cli_state *cli) return ret; } - if (!cli_check_sign_mac(cli)) { + if (!cli_check_sign_mac(cli, True)) { DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = READ_BAD_SIG; close(cli->fd); diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 9010dbf5cb..28ff0e0c2e 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -150,7 +150,7 @@ static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - NULL implementation - check a MAC sent by server. ************************************************************/ -static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok) { return True; } @@ -197,25 +197,39 @@ static void free_signing_context(struct smb_sign_info *si) } -static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq) +static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL expected_ok) { - if (good && !si->doing_signing) { - si->doing_signing = True; - } + if (good) { - if (!good) { - if (si->doing_signing) { - struct smb_basic_signing_context *data = si->signing_context; + if (!si->doing_signing) { + si->doing_signing = True; + } + + if (!si->seen_valid) { + si->seen_valid = True; + } - /* W2K sends a bad first signature but the sign engine is on.... JRA. */ - if (data->send_seq_num > 1) - DEBUG(1, ("signing_good: SMB signature check failed on seq %u!\n", - (unsigned int)seq )); + } else { + if (!si->mandatory_signing && !si->seen_valid) { - return False; - } else { - DEBUG(3, ("signing_good: Peer did not sign reply correctly\n")); + if (!expected_ok) { + return True; + } + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ + DEBUG(5, ("signing_good: signing negotiated but not required and the other side \ +isn't sending correct signatures. Turning signatures off.\n")); + si->negotiated_smb_signing = False; + si->allow_smb_signing = False; + si->doing_signing = False; free_signing_context(si); + return True; + } else if (!expected_ok) { + /* This packet is known to be unsigned */ + return True; + } else { + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + if (seq) + DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); return False; } } @@ -323,7 +337,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok) { BOOL good; uint32 reply_seq_number; @@ -381,7 +395,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, (const char *)server_sent_mac, 8); } - return signing_good(inbuf, si, good, saved_seq); + return signing_good(inbuf, si, good, saved_seq, expected_ok); } /*********************************************************** @@ -415,7 +429,7 @@ static void simple_free_signing_context(struct smb_sign_info *si) BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, - const DATA_BLOB response, int initial_send_seq_num) + const DATA_BLOB response) { struct smb_basic_signing_context *data; @@ -453,7 +467,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); /* Initialise the sequence number */ - data->send_seq_num = initial_send_seq_num; + data->send_seq_num = 0; /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; @@ -535,7 +549,7 @@ static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok) { return True; } @@ -597,9 +611,9 @@ void cli_calculate_sign_mac(struct cli_state *cli) * which had a bad checksum, True otherwise. */ -BOOL cli_check_sign_mac(struct cli_state *cli) +BOOL cli_check_sign_mac(struct cli_state *cli, BOOL expected_ok) { - if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) { + if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, expected_ok)) { free_signing_context(&cli->sign_info); return False; } @@ -688,7 +702,7 @@ static BOOL is_oplock_break(char *inbuf) SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ -static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL expected_ok) { BOOL good; struct smb_basic_signing_context *data = si->signing_context; @@ -762,25 +776,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); dump_data(10, (const char *)server_sent_mac, 8); } - if (!signing_good(inbuf, si, good, saved_seq)) { - if (!si->mandatory_signing && (data->send_seq_num < 3)){ - /* Non-mandatory signing - just turn off if this is the first bad packet.. */ - DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ -isn't sending correct signatures. Turning off.\n")); - si->negotiated_smb_signing = False; - si->allow_smb_signing = False; - si->doing_signing = False; - free_signing_context(si); - return True; - } else { - /* Mandatory signing or bad packet after signing started - fail and disconnect. */ - if (saved_seq) - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u\n", (unsigned int)saved_seq)); - return False; - } - } else { - return True; - } + return (signing_good(inbuf, si, good, saved_seq, expected_ok)); } /*********************************************************** @@ -813,13 +809,13 @@ BOOL srv_oplock_set_signing(BOOL onoff) Called to validate an incoming packet from the client. ************************************************************/ -BOOL srv_check_sign_mac(char *inbuf) +BOOL srv_check_sign_mac(char *inbuf, BOOL expected_ok) { /* Check if it's a session keepalive. */ if(CVAL(inbuf,0) == SMBkeepalive) return True; - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info); + return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, expected_ok); } /*********************************************************** @@ -907,6 +903,42 @@ BOOL srv_is_signing_active(void) return srv_sign_info.doing_signing; } + +/*********************************************************** + Returns whether signing is negotiated. We can't use it unless it was + in the negprot. +************************************************************/ + +BOOL srv_is_signing_negotiated(void) +{ + return srv_sign_info.negotiated_smb_signing; +} + +/*********************************************************** + Returns whether signing is negotiated. We can't use it unless it was + in the negprot. +************************************************************/ + +BOOL srv_signing_started(void) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) { + return False; + } + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data) + return False; + + if (data->send_seq_num == 0) { + return False; + } + + return True; +} + + /*********************************************************** Tell server code we are in a multiple trans reply state. ************************************************************/ diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 8438f2a593..ba57fecd51 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -275,7 +275,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, vuser->homes_snum = -1; } - if (lp_server_signing() && !vuser->guest && !srv_is_signing_active()) { + if (srv_is_signing_negotiated() && !vuser->guest && !srv_signing_started()) { /* Try and turn on server signing on the first non-guest sessionsetup. */ srv_set_signing(vuser->session_key, response_blob); } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c42a35e809..c66ccfd8eb 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -287,14 +287,14 @@ static int reply_spnego_kerberos(connection_struct *conn, SSVAL(outbuf, smb_uid, sess_vuid); - if (!server_info->guest) { + if (!server_info->guest && !srv_signing_started()) { /* We need to start the signing engine * here but a W2K client sends the old * "BSRSPYL " signature instead of the * correct one. Subsequent packets will * be correct. */ - srv_check_sign_mac(inbuf); + srv_check_sign_mac(inbuf, False); } } @@ -360,14 +360,15 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out SSVAL(outbuf,smb_uid,sess_vuid); - if (!server_info->guest) { + if (!server_info->guest && !srv_signing_started()) { /* We need to start the signing engine * here but a W2K client sends the old * "BSRSPYL " signature instead of the * correct one. Subsequent packets will * be correct. */ - srv_check_sign_mac(inbuf); + + srv_check_sign_mac(inbuf, False); } } } @@ -907,7 +908,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - if (!server_info->guest && !srv_check_sign_mac(inbuf)) { + if (!server_info->guest && !srv_signing_started() && !srv_check_sign_mac(inbuf, True)) { exit_server("reply_sesssetup_and_X: bad smb signature"); } -- cgit From 4aeb6b32a35edb52a2e000008d1fb24ba9fe4483 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 9 Mar 2004 15:29:40 +0000 Subject: fix build with gcc 2.96 and --with-developer (This used to be commit 45b2efd60a3c3c9f01b1ccaa828904a70d70d67d) --- source3/smbd/reply.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 1ff969493e..5bf8ca0a2d 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -146,10 +146,10 @@ size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len { pstring tmppath; char *tmppath_ptr = tmppath; + size_t ret; #ifdef DEVELOPER SMB_ASSERT(dest_len == sizeof(pstring)); #endif - size_t ret; if (src_len == 0) { ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags); -- cgit From 5e2282b94f862cc29114839ef6e379dbd24ba4b5 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 9 Mar 2004 18:56:28 +0000 Subject: Fix to debug message lacking termination with '\n'. rafal (This used to be commit 6fdb20f5a7657556a3e4ceb4cab8c1d67e29ea21) --- source3/groupdb/mapping.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index ef0708b888..bd387ee319 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -167,7 +167,7 @@ static BOOL add_mapping_entry(GROUP_MAP *map, int flag) int len; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } @@ -198,7 +198,7 @@ BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_us GROUP_MAP map; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } @@ -227,7 +227,7 @@ static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map) int ret = 0; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } @@ -269,7 +269,7 @@ static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map) int ret; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } @@ -319,7 +319,7 @@ static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map) int ret; if(!init_group_mapping()) { - DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping")); + DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping\n")); return(False); } @@ -369,7 +369,7 @@ static BOOL group_map_remove(DOM_SID sid) fstring string_sid; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } @@ -409,7 +409,7 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, int entries=0; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } @@ -489,7 +489,7 @@ static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member) int result; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return NT_STATUS_ACCESS_DENIED; } @@ -540,7 +540,7 @@ static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num) const char *p; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return NT_STATUS_ACCESS_DENIED; } @@ -741,7 +741,7 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) BOOL ret; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } @@ -790,7 +790,7 @@ BOOL get_local_group_from_sid(DOM_SID *sid, GROUP_MAP *map) BOOL ret; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } @@ -850,7 +850,7 @@ BOOL get_builtin_group_from_sid(DOM_SID *sid, GROUP_MAP *map) if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } @@ -887,7 +887,7 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) BOOL ret; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } @@ -947,7 +947,7 @@ BOOL get_sid_list_of_group(gid_t gid, DOM_SID **sids, int *num_sids) struct sys_pwent *user; if(!init_group_mapping()) { - DEBUG(0,("failed to initialize group mapping")); + DEBUG(0,("failed to initialize group mapping\n")); return(False); } -- cgit From 93f4a34978e89a2158569aa7a20c28a01e27df30 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 9 Mar 2004 20:30:35 +0000 Subject: 1) Two new functions to trust passwords interface in passdb: settrustpwent, gettrustpwnam 2) Implementation of another couple of these functions in tdbsam: settrustpwent, gettrustpwnam, gettrustpwsid 3) Testing (mostly for now) usage of the interface in pdbedit which is soon to be offline tool back again. This is quite a new code, so many changes will be put in soon. rafal (This used to be commit 2ed23fbce846f9710747d72aa98c20d54894d61e) --- source3/include/passdb.h | 10 ++- source3/passdb/pdb_interface.c | 67 +++++++++++++++++++ source3/passdb/pdb_tdb.c | 79 ++++++++++++++++++++-- source3/utils/pdbedit.c | 146 ++++++++++++++++++++++++++++++++++++----- 4 files changed, 280 insertions(+), 22 deletions(-) diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 65e342080e..df7c969633 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -262,7 +262,7 @@ typedef struct sam_trust_passwd { * this SAMBA will load. Increment this if *ANY* changes are made to the interface. */ -#define PASSDB_INTERFACE_VERSION 5 +#define PASSDB_INTERFACE_VERSION 6 typedef struct pdb_context { @@ -352,9 +352,13 @@ typedef struct pdb_context NTSTATUS (*pdb_get_group_uids)(struct pdb_context *context, const DOM_SID *group, uid_t **members, int *num_members); /* trust password functions */ + + NTSTATUS (*pdb_settrustpwent)(struct pdb_context *context); NTSTATUS (*pdb_gettrustpwent)(struct pdb_context *context, SAM_TRUST_PASSWD *trust); + NTSTATUS (*pdb_gettrustpwnam)(struct pdb_context *context, SAM_TRUST_PASSWD *trust, const char *dom_name); + NTSTATUS (*pdb_gettrustpwsid)(struct pdb_context *context, SAM_TRUST_PASSWD *trust, const DOM_SID *sid); NTSTATUS (*pdb_add_trust_passwd)(struct pdb_context *context, SAM_TRUST_PASSWD* trust); @@ -467,8 +471,12 @@ typedef struct pdb_methods /* trust password functions */ + NTSTATUS (*settrustpwent)(struct pdb_methods *methods); + NTSTATUS (*gettrustpwent)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust); + NTSTATUS (*gettrustpwnam)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const char *name); + NTSTATUS (*gettrustpwsid)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const DOM_SID *sid); NTSTATUS (*add_trust_passwd)(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust); diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 8307919d10..5679d4a5e8 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -487,6 +487,30 @@ static NTSTATUS context_enum_alias_memberships(struct pdb_context *context, num); } +static NTSTATUS context_settrustpwent(struct pdb_context *context) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + struct pdb_methods *cur_methods; + + if (!context) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + cur_methods = context->pdb_methods; + + while (cur_methods) { + ret = cur_methods->settrustpwent(cur_methods); + if (NT_STATUS_IS_OK(ret)) { + context->pdb_methods = cur_methods; + return ret; + } + cur_methods = cur_methods->next; + } + + return ret; +} + static NTSTATUS context_gettrustpwent(struct pdb_context *context, SAM_TRUST_PASSWD *trust) { @@ -502,6 +526,34 @@ static NTSTATUS context_gettrustpwent(struct pdb_context *context, while (cur_methods) { ret = cur_methods->gettrustpwent(cur_methods, trust); + if (!NT_STATUS_IS_ERR(ret)) { + /* prevent from segfaulting when gettrustpwent + was called just to rewind enumeration */ + if (trust) trust->methods = cur_methods; + return ret; + } + cur_methods = cur_methods->next; + } + + return ret; +} + +static NTSTATUS context_gettrustpwnam(struct pdb_context *context, + SAM_TRUST_PASSWD *trust, + const char *name) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + struct pdb_methods *cur_methods; + + if (!context) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + cur_methods = context->pdb_methods; + + while (cur_methods) { + ret = cur_methods->gettrustpwnam(cur_methods, trust, name); if (NT_STATUS_IS_OK(ret)) { trust->methods = cur_methods; return ret; @@ -786,7 +838,9 @@ static NTSTATUS make_pdb_context(struct pdb_context **context) (*context)->pdb_del_aliasmem = context_del_aliasmem; (*context)->pdb_enum_aliasmem = context_enum_aliasmem; (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships; + (*context)->pdb_settrustpwent = context_settrustpwent; (*context)->pdb_gettrustpwent = context_gettrustpwent; + (*context)->pdb_gettrustpwnam = context_gettrustpwnam; (*context)->pdb_gettrustpwsid = context_gettrustpwsid; (*context)->pdb_add_trust_passwd = context_add_trust_passwd; (*context)->pdb_update_trust_passwd = context_update_trust_passwd; @@ -1261,11 +1315,22 @@ static void pdb_default_endsampwent(struct pdb_methods *methods) return; /* NT_STATUS_NOT_IMPLEMENTED; */ } +static NTSTATUS pdb_default_settrustpwent(struct pdb_methods *methods) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + static NTSTATUS pdb_default_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust) { return NT_STATUS_NOT_IMPLEMENTED; } +static NTSTATUS pdb_default_gettrustpwnam(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust, + const char* name) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + static NTSTATUS pdb_default_gettrustpwsid(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust, const DOM_SID* sid) { @@ -1341,7 +1406,9 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) (*methods)->enum_aliasmem = pdb_default_enum_aliasmem; (*methods)->enum_alias_memberships = pdb_default_alias_memberships; + (*methods)->settrustpwent = pdb_default_settrustpwent; (*methods)->gettrustpwent = pdb_default_gettrustpwent; + (*methods)->gettrustpwnam = pdb_default_gettrustpwnam; (*methods)->gettrustpwsid = pdb_default_gettrustpwsid; (*methods)->add_trust_passwd = pdb_default_add_trust_passwd; (*methods)->update_trust_passwd = pdb_default_update_trust_passwd; diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 39de791b07..aef088c124 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -699,8 +699,22 @@ static void free_private_data(void **vp) } /** - * Start enumerating through trust passwords (machine and - * interdomain nt/ads) + * Start trust passwords enumeration. This function is a simple + * wrapper for calling gettrustpwent with null pointer passed. + * + * @param methods methods belonging in pdb context (module) + * @return nt status of performed operation + **/ + +static NTSTATUS tdbsam_settrustpwent(struct pdb_methods *methods) +{ + /* rewind enumeration from beginning */ + return methods->gettrustpwent(methods, NULL); +} + + +/** + * Enumerate across trust passwords (machine and interdomain nt/ads) * * @param methods methods belonging in pdb context (module) * @param trust trust password structure @@ -782,7 +796,7 @@ static NTSTATUS tdbsam_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASS talloc_destroy(mem_ctx); trust->private = t; - return NT_STATUS_OK; + return NT_STATUS_NO_MORE_ENTRIES; } secrets_lock_trust_account_password(lp_workgroup(), False); } else { @@ -793,11 +807,55 @@ static NTSTATUS tdbsam_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASS /* * ADS machine trust password (TODO) */ + + + /* + * if nothing is to be returned then reset domain name + * and return "no more entries" + */ + nt_status = NT_STATUS_NO_MORE_ENTRIES; + trust->private.uni_name_len = 0; + trust->private.uni_name[t.uni_name_len] = 0; talloc_destroy(mem_ctx); return nt_status; } + +/** + * Get trust password by trusted party name + * + * @param methods methods belonging to pdb context (module) + * @param trust trust password structure + * @param sid trusted party name + * + * @return nt status of performed operation + **/ + +static NTSTATUS tdbsam_gettrustpwnam(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, + const char *name) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + char domain_name[32]; + + if (!methods || !trust || !name) return nt_status; + + do { + /* get trust password (next in turn) */ + nt_status = tdbsam_gettrustpwent(methods, trust); + + /* convert unicode name and do case insensitive compare */ + pull_ucs2(NULL, domain_name, trust->private.uni_name, sizeof(domain_name), + trust->private.uni_name_len, STR_TERMINATE); + if (!StrnCaseCmp(domain_name, name, sizeof(domain_name))) + return NT_STATUS_OK; + + } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); + + return nt_status; +} + + /** * Get trust password by trusted party sid * @@ -811,7 +869,18 @@ static NTSTATUS tdbsam_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASS static NTSTATUS tdbsam_gettrustpwsid(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const DOM_SID *sid) { - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + + if (!methods || !trust || !sid) return nt_status; + + do { + nt_status = tdbsam_gettrustpwent(methods, trust); + + if (sid_equal(&trust->private.domain_sid, sid)) + return NT_STATUS_OK; + + } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); + return nt_status; } @@ -1263,7 +1332,9 @@ static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_meth (*pdb_method)->add_sam_account = tdbsam_add_sam_account; (*pdb_method)->update_sam_account = tdbsam_update_sam_account; (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account; + (*pdb_method)->settrustpwent = tdbsam_settrustpwent; (*pdb_method)->gettrustpwent = tdbsam_gettrustpwent; + (*pdb_method)->gettrustpwnam = tdbsam_gettrustpwnam; (*pdb_method)->gettrustpwsid = tdbsam_gettrustpwsid; (*pdb_method)->add_trust_passwd = tdbsam_add_trust_passwd; (*pdb_method)->update_trust_passwd = tdbsam_update_trust_passwd; diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 4178afdaf8..e744f359d3 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -228,6 +228,88 @@ static int print_user_info (struct pdb_context *in, const char *username, BOOL v return ret; } + + +static int trustpw_flag(const char* flag_name) +{ + const int flag_num = 5; + typedef struct { const char *name; int val; } flag_conv; + flag_conv flags[] = {{ "PASS_MACHINE_TRUST_NT", PASS_MACHINE_TRUST_NT }, + { "PASS_SERVER_TRUST_NT", PASS_SERVER_TRUST_NT }, + { "PASS_DOMAIN_TRUST_NT", PASS_DOMAIN_TRUST_NT }, + { "PASS_MACHINE_TRUST_ADS",PASS_MACHINE_TRUST_ADS }, + { "PASS_DOMAIN_TRUST_ADS", PASS_DOMAIN_TRUST_ADS }}; + int i; + + for (i = 0; i < flag_num; i++) { + if (!StrCaseCmp(flags[i].name, flag_name)) { + return flags[i].val; + } + } + + return 0; +} + + +static char* trustpw_flag_name(const int val) +{ + const int flag_num = 5; + typedef struct { const char *name; int val; } flag_conv; + flag_conv flags[] = {{ "PASS_MACHINE_TRUST_NT", PASS_MACHINE_TRUST_NT }, + { "PASS_SERVER_TRUST_NT", PASS_SERVER_TRUST_NT }, + { "PASS_DOMAIN_TRUST_NT", PASS_DOMAIN_TRUST_NT }, + { "PASS_MACHINE_TRUST_ADS",PASS_MACHINE_TRUST_ADS }, + { "PASS_DOMAIN_TRUST_ADS", PASS_DOMAIN_TRUST_ADS }}; + int i; + + for (i = 0; i < flag_num; i++) { + if (flags[i].val == val) { + return strdup(flags[i].name); + } + } + + return strdup("unknown flag"); +} + + +static int print_trustpw_info(TALLOC_CTX *mem_ctx, SAM_TRUST_PASSWD *trust, BOOL verbose) +{ + char *dom_name; + if (!mem_ctx || !trust) return -1; + + /* convert unicode domain name to char* */ + if (!pull_ucs2_talloc(mem_ctx, &dom_name, trust->private.uni_name)) return -1; + dom_name[trust->private.uni_name_len] = 0; + + /* different output depending on level of verbosity */ + if (verbose) { + printf("Domain name: %s\n", dom_name); + printf("Domain SID: %s\n", sid_string_static(&trust->private.domain_sid)); + printf("Trust password %s\n", trust->private.pass); + printf("Trust type: %s\n", trustpw_flag_name(trust->private.flags)); + printf("Last modified %s\n", trust->private.mod_time ? http_timestring(trust->private.mod_time) : "0"); + + } else { + printf("%s:%s\n", dom_name, sid_string_static(&trust->private.domain_sid)); + } + + return 0; +} + + +static int print_trust_info(struct pdb_context *in, const char *name, BOOL verbose, BOOL smbpwdstyle) +{ + SAM_TRUST_PASSWD trust; + TALLOC_CTX *mem_ctx = NULL; + + mem_ctx = talloc_init("pdbedit: trust passwords listing"); + + if (NT_STATUS_IS_OK(in->pdb_gettrustpwnam(in, &trust, name))) { + return print_trustpw_info(mem_ctx, &trust, verbose); + } + + return -1; +} /********************************************************* List Users @@ -258,6 +340,46 @@ static int print_users_list (struct pdb_context *in, BOOL verbosity, BOOL smbpwd return 0; } +/** + * List trust passwords + * + * @param in initialised pdb context + * @param verbose turn on/off verbose mode + * @param smbpwdstyle ignored here (there was no trust passwords in smbpasswd file) + * @return 0 on success, otherwise failure + **/ + +static int print_trustpw_list(struct pdb_context *in, BOOL verbose, BOOL smbpwdstyle) +{ + SAM_TRUST_PASSWD trust; + TALLOC_CTX *mem_ctx = NULL; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + /* start enumeration and initialise memory context */ + status = in->pdb_settrustpwent(in); + if (NT_STATUS_IS_ERR(status)) return -1; + mem_ctx = talloc_init("pdbedit: trust passwords listing"); + + /* small separation to make it clear these are not regular accounts */ + if (!verbose) printf("---\n"); + + do { + /* fetch next trust password */ + status = in->pdb_gettrustpwent(in, &trust); + + if (trust.private.uni_name_len) { + /* print trust password info */ + if (verbose) printf ("---------------\n"); + print_trustpw_info(mem_ctx, &trust, verbose); + } + + } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(status, NT_STATUS_OK)); + + talloc_destroy(mem_ctx); + return 0; +} + + /********************************************************* Fix a list of Users for uninitialised passwords **********************************************************/ @@ -573,14 +695,6 @@ static int new_trustdom(struct pdb_context *in, const char *dom_name) static int new_trustpw(struct pdb_context *in, const char *dom_name, const char *dom_sid, const char* flag) { - const int flag_num = 5; - typedef struct { const char *name; int val; } flag_conv; - flag_conv flags[] = {{ "PASS_MACHINE_TRUST_NT", PASS_MACHINE_TRUST_NT }, - { "PASS_SERVER_TRUST_NT", PASS_SERVER_TRUST_NT }, - { "PASS_DOMAIN_TRUST_NT", PASS_DOMAIN_TRUST_NT }, - { "PASS_MACHINE_TRUST_ADS",PASS_MACHINE_TRUST_ADS }, - { "PASS_DOMAIN_TRUST_ADS", PASS_DOMAIN_TRUST_ADS }}; - TALLOC_CTX *mem_ctx = NULL; SAM_TRUST_PASSWD trust; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; @@ -591,7 +705,6 @@ static int new_trustpw(struct pdb_context *in, const char *dom_name, struct in_addr srv_ip; fstring srv_name, myname; struct cli_state *cli; - int i; time_t lct; if (!dom_name) return -1; @@ -604,12 +717,7 @@ static int new_trustpw(struct pdb_context *in, const char *dom_name, strncpy_w(trust.private.uni_name, uni_name, 32); /* flags */ - for (i = 0; i < flag_num; i++) { - if (!StrCaseCmp(flags[i].name, flag)) { - trust.private.flags = flags[i].val; - i = flag_num; /* stop comparing */ - } - } + trust.private.flags = trustpw_flag(flag); /* trusting SID */ if (!dom_sid) { @@ -952,10 +1060,14 @@ int main (int argc, char **argv) /* list users operations */ if (checkparms & BIT_LIST) { if (!(checkparms & ~BIT_LIST)) { - return print_users_list (bdef, verbose, spstyle); + print_users_list (bdef, verbose, spstyle); + return print_trustpw_list(bdef, verbose, spstyle); } if (!(checkparms & ~(BIT_USER + BIT_LIST))) { return print_user_info (bdef, user_name, verbose, spstyle); + + } else if (!(checkparms & ~(BIT_TRUSTPW + BIT_LIST))) { + return print_trust_info(bdef, trustpw, verbose, spstyle); } } @@ -1019,7 +1131,7 @@ int main (int argc, char **argv) /* trust password creation */ if (!(checkparms & ~(BIT_CREATE + BIT_TRUSTPW + BIT_TRUSTSID + BIT_TRUSTFLAGS))) { return new_trustpw(bdef, trustpw, trustsid, trustflags); - } + } } -- cgit From 340c4bbe5dfdf173013420edbacfdbe8f8c00a3f Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 9 Mar 2004 20:44:39 +0000 Subject: Forgot to put some more comments. rafal (This used to be commit b3efdcf0aeec5a115c53de8bbedaa9ca8225b689) --- source3/utils/pdbedit.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index e744f359d3..af96413c5a 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -230,6 +230,13 @@ static int print_user_info (struct pdb_context *in, const char *username, BOOL v } +/** + * Trust password flag name to flag conversion + * + * @param flag_name SAM_TRUST_PASSWD structure flag name + * @return flag value + **/ + static int trustpw_flag(const char* flag_name) { const int flag_num = 5; @@ -251,6 +258,13 @@ static int trustpw_flag(const char* flag_name) } +/** + * Trust password flag to flag name conversion + * + * @param val SAM_TRUST_PASSWD structure flag + * @return passed flag name + **/ + static char* trustpw_flag_name(const int val) { const int flag_num = 5; @@ -272,6 +286,15 @@ static char* trustpw_flag_name(const int val) } +/** + * Print trust password structure information + * + * @param mem_ctx memory context (for unicode name conversion) + * @param trust SAM_TRUST_PASSWD structure + * @param verbose verbose mode on/off + * @return 0 on success, otherwise failure + **/ + static int print_trustpw_info(TALLOC_CTX *mem_ctx, SAM_TRUST_PASSWD *trust, BOOL verbose) { char *dom_name; @@ -297,6 +320,16 @@ static int print_trustpw_info(TALLOC_CTX *mem_ctx, SAM_TRUST_PASSWD *trust, BOOL } +/** + * Print trust password information by given name + * + * @param in initialised pdb_context + * @param name domain name of the trust password + * @param verbose verbose mode on/off + * @param smbpwdstyle smbpassword-style output (ignored here) + * @return 0 on success, otherwise failure + **/ + static int print_trust_info(struct pdb_context *in, const char *name, BOOL verbose, BOOL smbpwdstyle) { SAM_TRUST_PASSWD trust; @@ -340,6 +373,7 @@ static int print_users_list (struct pdb_context *in, BOOL verbosity, BOOL smbpwd return 0; } + /** * List trust passwords * -- cgit From 104e6c43ed1f9732242db74792704beaf5fc302c Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 9 Mar 2004 21:48:46 +0000 Subject: Yet another '\n' termination of debug message. rafal (This used to be commit 6c8e39b7ccc1ad8e7f39c2a51fa13423e5d6e227) --- source3/smbd/ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index dd92cc4e4d..e5465b902c 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -293,7 +293,7 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf, return api_no_reply(outbuf, mdrcnt); } - DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)", subcommand, p->name, pnum)); + DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n", subcommand, p->name, pnum)); /* record maximum data length that can be transmitted in an SMBtrans */ p->max_trans_reply = mdrcnt; -- cgit From 0060085a837cbeb049d51a254fbe83b8eea685bb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Mar 2004 23:26:56 +0000 Subject: Fix dfs referrals - don't use check_path_syntax. Also use mb char calls in dfs code. Jeremy. (This used to be commit 70670841028aaeb72267ac41ca30af8dba412998) --- source3/msdfs/msdfs.c | 19 +++++++++---------- source3/smbd/trans2.c | 7 +------ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index cd83756056..081ce809cf 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -45,7 +45,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp) /* now tokenize */ /* parse out hostname */ - p = strchr(temp,'\\'); + p = strchr_m(temp,'\\'); if(p == NULL) return False; *p = '\0'; @@ -54,7 +54,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp) /* parse out servicename */ temp = p+1; - p = strchr(temp,'\\'); + p = strchr_m(temp,'\\'); if(p == NULL) { pstrcpy(pdp->servicename,temp); pdp->reqpath[0] = '\0'; @@ -67,9 +67,8 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp) /* rest is reqpath */ pstrcpy(pdp->reqpath, p+1); p = pdp->reqpath; - while (*p) { - if (*p == '\\') *p = '/'; - p++; + while ((p = strchr_m(p, '\\'))!=NULL) { + *p++ = '/'; } DEBUG(10,("rest of the path: %s\n",pdp->reqpath)); @@ -148,7 +147,7 @@ static BOOL parse_symlink(char* buf,struct referral** preflist, for(i=0;ireqpath); - p = strrchr(reqpath, '/'); + p = strrchr_m(reqpath, '/'); while (p) { *p = '\0'; pstrcpy(localpath, reqpath); @@ -288,7 +287,7 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp, pstrcpy(buf, dfspath); trim_char(buf, '\0', '\\'); for (; consumed_level; consumed_level--) { - q = strrchr(buf, '\\'); + q = strrchr_m(buf, '\\'); if (q) *q = 0; } @@ -298,7 +297,7 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp, return True; } - p = strrchr(reqpath, '/'); + p = strrchr_m(reqpath, '/'); consumed_level++; } @@ -526,7 +525,7 @@ static int setup_ver2_dfs_referral(char* pathname, char** ppdata, offset = 8; /* add the referral elements */ for(i=0;ireferral_count;i++) { - struct referral* ref = &(junction->referral_list[i]); + struct referral* ref = &junction->referral_list[i]; int unilen; SSVAL(pdata,offset,2); /* version 2 */ diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 38fed4beae..19269cbc6c 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3390,7 +3390,6 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, pstring pathname; int reply_size = 0; int max_referral_level; - NTSTATUS status = NT_STATUS_OK; DEBUG(10,("call_trans2getdfsreferral\n")); @@ -3402,11 +3401,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, if(!lp_host_msdfs()) return ERROR_DOS(ERRDOS,ERRbadfunc); - srvstr_get_path(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE, &status); - if (!NT_STATUS_IS_OK(status)) { - return ERROR_NT(status); - } - + srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE); if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0) return UNIXERROR(ERRDOS,ERRbadfile); -- cgit From 0b85e6e157ca31b2932a48cc265d58cffa2c9177 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 10 Mar 2004 00:52:59 +0000 Subject: fix type for tag in proto file (This used to be commit cd1ed1a23b15002aab3387c6f6316f85574c11e8) --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 0008a85f75..b012c6c185 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1422,7 +1422,7 @@ client/client_proto.h: utils/net_proto.h: @cd $(srcdir) && $(SHELL) $(MKPROTO_SH) $(AWK) \ - -h _CLIENT_PROTO_H_ $(builddir)/utils/net_proto.h \ + -h _NET_PROTO_H_ $(builddir)/utils/net_proto.h \ $(NET_OBJ1) include/tdbsam2_parse_info.h: -- cgit From 317c529e51b12aea2e79d7a5399c1ffc6ab54e66 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Mar 2004 01:32:24 +0000 Subject: Formatting reformat before I start to change anything here. Jeremy. (This used to be commit e93aeb96771125ef8775a531257e7390217204d0) --- source3/rpc_server/srv_dfs_nt.c | 531 +++++++++++++++++++--------------------- 1 file changed, 258 insertions(+), 273 deletions(-) diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c index f324fd126e..a3b06bb6e1 100644 --- a/source3/rpc_server/srv_dfs_nt.c +++ b/source3/rpc_server/srv_dfs_nt.c @@ -44,324 +44,309 @@ uint32 _dfs_exist(pipes_struct *p, DFS_Q_DFS_EXIST *q_u, DFS_R_DFS_EXIST *r_u) WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u) { - struct current_user user; - struct junction_map jn; - struct referral* old_referral_list = NULL; - BOOL exists = False; - - pstring dfspath, servername, sharename; - pstring altpath; - - get_current_user(&user,p); - - if (user.uid != 0) { - DEBUG(10,("_dfs_add: uid != 0. Access denied.\n")); - return WERR_ACCESS_DENIED; - } - - unistr2_to_ascii(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1); - unistr2_to_ascii(servername, &q_u->ServerName, sizeof(servername)-1); - unistr2_to_ascii(sharename, &q_u->ShareName, sizeof(sharename)-1); - - DEBUG(5,("init_reply_dfs_add: Request to add %s -> %s\\%s.\n", - dfspath, servername, sharename)); - - pstrcpy(altpath, servername); - pstrcat(altpath, "\\"); - pstrcat(altpath, sharename); - - /* The following call can change the cwd. */ - if(get_referred_path(dfspath, &jn, NULL, NULL)) - { - exists = True; - jn.referral_count += 1; - old_referral_list = jn.referral_list; - } - else - jn.referral_count = 1; - - vfs_ChDir(p->conn,p->conn->connectpath); - - jn.referral_list = (struct referral*) talloc(p->mem_ctx, jn.referral_count - * sizeof(struct referral)); - - if(jn.referral_list == NULL) - { - DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n")); - return WERR_DFS_INTERNAL_ERROR; - } - - if(old_referral_list) - { - memcpy(jn.referral_list, old_referral_list, - sizeof(struct referral)*jn.referral_count-1); - SAFE_FREE(old_referral_list); - } + struct current_user user; + struct junction_map jn; + struct referral* old_referral_list = NULL; + BOOL exists = False; + + pstring dfspath, servername, sharename; + pstring altpath; + + get_current_user(&user,p); + + if (user.uid != 0) { + DEBUG(10,("_dfs_add: uid != 0. Access denied.\n")); + return WERR_ACCESS_DENIED; + } + + unistr2_to_ascii(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1); + unistr2_to_ascii(servername, &q_u->ServerName, sizeof(servername)-1); + unistr2_to_ascii(sharename, &q_u->ShareName, sizeof(sharename)-1); + + DEBUG(5,("init_reply_dfs_add: Request to add %s -> %s\\%s.\n", + dfspath, servername, sharename)); + + pstrcpy(altpath, servername); + pstrcat(altpath, "\\"); + pstrcat(altpath, sharename); + + /* The following call can change the cwd. */ + if(get_referred_path(dfspath, &jn, NULL, NULL)) { + exists = True; + jn.referral_count += 1; + old_referral_list = jn.referral_list; + } else { + jn.referral_count = 1; + } + + vfs_ChDir(p->conn,p->conn->connectpath); + + jn.referral_list = (struct referral*) talloc(p->mem_ctx, jn.referral_count + * sizeof(struct referral)); + + if(jn.referral_list == NULL) { + DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n")); + return WERR_DFS_INTERNAL_ERROR; + } + + if(old_referral_list) { + memcpy(jn.referral_list, old_referral_list, sizeof(struct referral)*jn.referral_count-1); + SAFE_FREE(old_referral_list); + } - jn.referral_list[jn.referral_count-1].proximity = 0; - jn.referral_list[jn.referral_count-1].ttl = REFERRAL_TTL; + jn.referral_list[jn.referral_count-1].proximity = 0; + jn.referral_list[jn.referral_count-1].ttl = REFERRAL_TTL; - pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath); + pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath); - if(!create_msdfs_link(&jn, exists)) { - vfs_ChDir(p->conn,p->conn->connectpath); - return WERR_DFS_CANT_CREATE_JUNCT; - } - vfs_ChDir(p->conn,p->conn->connectpath); + if(!create_msdfs_link(&jn, exists)) { + vfs_ChDir(p->conn,p->conn->connectpath); + return WERR_DFS_CANT_CREATE_JUNCT; + } + vfs_ChDir(p->conn,p->conn->connectpath); - return WERR_OK; + return WERR_OK; } WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u) { - struct current_user user; - struct junction_map jn; - BOOL found = False; - - pstring dfspath, servername, sharename; - pstring altpath; - - get_current_user(&user,p); - - if (user.uid != 0) { - DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n")); - return WERR_ACCESS_DENIED; - } - - unistr2_to_ascii(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1); - if(q_u->ptr_ServerName) - unistr2_to_ascii(servername, &q_u->ServerName, sizeof(servername)-1); - - if(q_u->ptr_ShareName) - unistr2_to_ascii(sharename, &q_u->ShareName, sizeof(sharename)-1); - - if(q_u->ptr_ServerName && q_u->ptr_ShareName) - { - pstrcpy(altpath, servername); - pstrcat(altpath, "\\"); - pstrcat(altpath, sharename); - strlower_m(altpath); - } - - DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n", - dfspath, servername, sharename)); - - if(!get_referred_path(dfspath, &jn, NULL, NULL)) - return WERR_DFS_NO_SUCH_VOL; - - /* if no server-share pair given, remove the msdfs link completely */ - if(!q_u->ptr_ServerName && !q_u->ptr_ShareName) - { - if(!remove_msdfs_link(&jn)) { - vfs_ChDir(p->conn,p->conn->connectpath); - return WERR_DFS_NO_SUCH_VOL; - } - vfs_ChDir(p->conn,p->conn->connectpath); - } - else - { - int i=0; - /* compare each referral in the list with the one to remove */ - DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn.referral_count)); - for(i=0;iconn,p->conn->connectpath); - return WERR_DFS_NO_SUCH_VOL; - } - vfs_ChDir(p->conn,p->conn->connectpath); + + unistr2_to_ascii(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1); + if(q_u->ptr_ServerName) { + unistr2_to_ascii(servername, &q_u->ServerName, sizeof(servername)-1); + } + + if(q_u->ptr_ShareName) { + unistr2_to_ascii(sharename, &q_u->ShareName, sizeof(sharename)-1); + } + + if(q_u->ptr_ServerName && q_u->ptr_ShareName) { + pstrcpy(altpath, servername); + pstrcat(altpath, "\\"); + pstrcat(altpath, sharename); + strlower_m(altpath); + } + + DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n", + dfspath, servername, sharename)); + + if(!get_referred_path(dfspath, &jn, NULL, NULL)) { + return WERR_DFS_NO_SUCH_VOL; } - else - { - if(!create_msdfs_link(&jn, True)) { - vfs_ChDir(p->conn,p->conn->connectpath); - return WERR_DFS_CANT_CREATE_JUNCT; - } - vfs_ChDir(p->conn,p->conn->connectpath); + + /* if no server-share pair given, remove the msdfs link completely */ + if(!q_u->ptr_ServerName && !q_u->ptr_ShareName) { + if(!remove_msdfs_link(&jn)) { + vfs_ChDir(p->conn,p->conn->connectpath); + return WERR_DFS_NO_SUCH_VOL; + } + vfs_ChDir(p->conn,p->conn->connectpath); + } else { + int i=0; + /* compare each referral in the list with the one to remove */ + DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn.referral_count)); + for(i=0;iconn,p->conn->connectpath); + return WERR_DFS_NO_SUCH_VOL; + } + } else { + if(!create_msdfs_link(&jn, True)) { + vfs_ChDir(p->conn,p->conn->connectpath); + return WERR_DFS_CANT_CREATE_JUNCT; + } + } + vfs_ChDir(p->conn,p->conn->connectpath); } - } - return WERR_OK; + return WERR_OK; } static BOOL init_reply_dfs_info_1(struct junction_map* j, DFS_INFO_1* dfs1, int num_j) { - int i=0; - for(i=0;ialternate_path); - trim_char(path,'\\','\0'); - p = strrchr_m(path,'\\'); - if(p==NULL) - { - DEBUG(4,("init_reply_dfs_info_3: invalid path: no \\ found in %s\n",path)); - continue; - } - *p = '\0'; - DEBUG(5,("storage %d: %s.%s\n",ii,path,p+1)); - stor->state = 2; /* set all storages as ONLINE */ - init_unistr2(&stor->servername, path, UNI_STR_TERMINATE); - init_unistr2(&stor->sharename, p+1, UNI_STR_TERMINATE); - stor->ptr_servername = stor->ptr_sharename = 1; + pstrcpy(path, ref->alternate_path); + trim_char(path,'\\','\0'); + p = strrchr_m(path,'\\'); + if(p==NULL) { + DEBUG(4,("init_reply_dfs_info_3: invalid path: no \\ found in %s\n",path)); + continue; + } + *p = '\0'; + DEBUG(5,("storage %d: %s.%s\n",ii,path,p+1)); + stor->state = 2; /* set all storages as ONLINE */ + init_unistr2(&stor->servername, path, UNI_STR_TERMINATE); + init_unistr2(&stor->sharename, p+1, UNI_STR_TERMINATE); + stor->ptr_servername = stor->ptr_sharename = 1; + } } - } - return True; + return True; } static WERROR init_reply_dfs_ctr(TALLOC_CTX *ctx, uint32 level, DFS_INFO_CTR* ctr, struct junction_map* jn, int num_jn) { - /* do the levels */ - switch(level) - { - case 1: - { - DFS_INFO_1* dfs1; - dfs1 = (DFS_INFO_1*) talloc(ctx, num_jn * sizeof(DFS_INFO_1)); - if (!dfs1) - return WERR_NOMEM; - init_reply_dfs_info_1(jn, dfs1, num_jn); - ctr->dfs.info1 = dfs1; - break; - } - case 2: - { - DFS_INFO_2* dfs2; - dfs2 = (DFS_INFO_2*) talloc(ctx, num_jn * sizeof(DFS_INFO_2)); - if (!dfs2) - return WERR_NOMEM; - init_reply_dfs_info_2(jn, dfs2, num_jn); - ctr->dfs.info2 = dfs2; - break; - } - case 3: - { - DFS_INFO_3* dfs3; - dfs3 = (DFS_INFO_3*) talloc(ctx, num_jn * sizeof(DFS_INFO_3)); - if (!dfs3) - return WERR_NOMEM; - init_reply_dfs_info_3(ctx, jn, dfs3, num_jn); - ctr->dfs.info3 = dfs3; - break; - } + /* do the levels */ + switch(level) { + case 1: + { + DFS_INFO_1* dfs1; + dfs1 = (DFS_INFO_1*) talloc(ctx, num_jn * sizeof(DFS_INFO_1)); + if (!dfs1) + return WERR_NOMEM; + init_reply_dfs_info_1(jn, dfs1, num_jn); + ctr->dfs.info1 = dfs1; + break; + } + case 2: + { + DFS_INFO_2* dfs2; + dfs2 = (DFS_INFO_2*) talloc(ctx, num_jn * sizeof(DFS_INFO_2)); + if (!dfs2) + return WERR_NOMEM; + init_reply_dfs_info_2(jn, dfs2, num_jn); + ctr->dfs.info2 = dfs2; + break; + } + case 3: + { + DFS_INFO_3* dfs3; + dfs3 = (DFS_INFO_3*) talloc(ctx, num_jn * sizeof(DFS_INFO_3)); + if (!dfs3) + return WERR_NOMEM; + init_reply_dfs_info_3(ctx, jn, dfs3, num_jn); + ctr->dfs.info3 = dfs3; + break; + } default: return WERR_INVALID_PARAM; - } - return WERR_OK; + } + return WERR_OK; } WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u) { - uint32 level = q_u->level; - struct junction_map jn[MAX_MSDFS_JUNCTIONS]; - int num_jn = 0; + uint32 level = q_u->level; + struct junction_map jn[MAX_MSDFS_JUNCTIONS]; + int num_jn = 0; - num_jn = enum_msdfs_links(jn); - vfs_ChDir(p->conn,p->conn->connectpath); + num_jn = enum_msdfs_links(jn); + vfs_ChDir(p->conn,p->conn->connectpath); - DEBUG(5,("make_reply_dfs_enum: %d junctions found in Dfs, doing level %d\n", num_jn, level)); - - r_u->ptr_buffer = level; - r_u->level = r_u->level2 = level; - r_u->ptr_num_entries = r_u->ptr_num_entries2 = 1; - r_u->num_entries = r_u->num_entries2 = num_jn; - r_u->reshnd.ptr_hnd = 1; - r_u->reshnd.handle = num_jn; + DEBUG(5,("make_reply_dfs_enum: %d junctions found in Dfs, doing level %d\n", num_jn, level)); + + r_u->ptr_buffer = level; + r_u->level = r_u->level2 = level; + r_u->ptr_num_entries = r_u->ptr_num_entries2 = 1; + r_u->num_entries = r_u->num_entries2 = num_jn; + r_u->reshnd.ptr_hnd = 1; + r_u->reshnd.handle = num_jn; - r_u->ctr = (DFS_INFO_CTR*)talloc(p->mem_ctx, sizeof(DFS_INFO_CTR)); - if (!r_u->ctr) - return WERR_NOMEM; - ZERO_STRUCTP(r_u->ctr); - r_u->ctr->switch_value = level; - r_u->ctr->num_entries = num_jn; - r_u->ctr->ptr_dfs_ctr = 1; + r_u->ctr = (DFS_INFO_CTR*)talloc(p->mem_ctx, sizeof(DFS_INFO_CTR)); + if (!r_u->ctr) + return WERR_NOMEM; + ZERO_STRUCTP(r_u->ctr); + r_u->ctr->switch_value = level; + r_u->ctr->num_entries = num_jn; + r_u->ctr->ptr_dfs_ctr = 1; - r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, r_u->ctr, jn, num_jn); + r_u->status = init_reply_dfs_ctr(p->mem_ctx, level, r_u->ctr, jn, num_jn); - return r_u->status; + return r_u->status; } WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, -- cgit From 73cd06319fb12d158e172c6416a9ee3f6031c1bf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Mar 2004 02:38:36 +0000 Subject: Moving towards getting msdfs working again (this looks like it was broken in 3.0.2a actually). We now send a correct referral back, but the client refuses to follow it... Not sure why. Will do more tests.. Maybe unicode character count is wrong (it looks it). Jeremy. (This used to be commit 859529aff348e66281d2ec4d54c5852121aae9e5) --- source3/msdfs/msdfs.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index 081ce809cf..41f66ecd51 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -50,7 +50,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp) return False; *p = '\0'; pstrcpy(pdp->hostname,temp); - DEBUG(10,("hostname: %s\n",pdp->hostname)); + DEBUG(10,("parse_dfs_path: hostname: %s\n",pdp->hostname)); /* parse out servicename */ temp = p+1; @@ -62,7 +62,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp) } *p = '\0'; pstrcpy(pdp->servicename,temp); - DEBUG(10,("servicename: %s\n",pdp->servicename)); + DEBUG(10,("parse_dfs_path: servicename: %s\n",pdp->servicename)); /* rest is reqpath */ pstrcpy(pdp->reqpath, p+1); @@ -71,7 +71,54 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp) *p++ = '/'; } - DEBUG(10,("rest of the path: %s\n",pdp->reqpath)); + DEBUG(10,("parse_dfs_path: rest of the path: %s\n",pdp->reqpath)); + return True; +} + +/********************************************************************** + Parse the pathname of the form /hostname/service/reqpath + into the dfs_path structure + **********************************************************************/ + +static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path* pdp) +{ + pstring pathname_local; + char* p,*temp; + + pstrcpy(pathname_local,pathname); + p = temp = pathname_local; + + ZERO_STRUCTP(pdp); + + trim_char(temp,'/','/'); + DEBUG(10,("temp in parse_processed_dfs_path: .%s. after trimming \\'s\n",temp)); + + /* now tokenize */ + /* parse out hostname */ + p = strchr_m(temp,'/'); + if(p == NULL) + return False; + *p = '\0'; + pstrcpy(pdp->hostname,temp); + DEBUG(10,("parse_processed_dfs_path: hostname: %s\n",pdp->hostname)); + + /* parse out servicename */ + temp = p+1; + p = strchr_m(temp,'/'); + if(p == NULL) { + pstrcpy(pdp->servicename,temp); + pdp->reqpath[0] = '\0'; + return True; + } + *p = '\0'; + pstrcpy(pdp->servicename,temp); + DEBUG(10,("parse_processed_dfs_path: servicename: %s\n",pdp->servicename)); + + /* rest is reqpath */ + /* JRA. We should do a check_path_syntax here.... TOFIX ! */ + pstrcpy(pdp->reqpath, p+1); + + DEBUG(10,("parse_processed_dfs_path: rest of the path: %s\n",pdp->reqpath)); return True; } @@ -99,11 +146,20 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path) talloc_destroy( conn->mem_ctx ); return False; } + + /* + * Windows seems to insist on doing trans2getdfsreferral() calls on the IPC$ + * share as the anonymous user. If we try to chdir as that user we will + * fail.... WTF ? JRA. + */ + if (vfs_ChDir(conn,conn->connectpath) != 0) { DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. Error was %s\n", conn->connectpath, strerror(errno) )); +#if 0 /* JRATEST ? */ talloc_destroy( conn->mem_ctx ); return False; +#endif } return True; } @@ -113,6 +169,7 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path) Parse the contents of a symlink to verify if it is an msdfs referral A valid referral is of the form: msdfs:server1\share1,server2\share2 **********************************************************************/ + static BOOL parse_symlink(char* buf,struct referral** preflist, int* refcount) { @@ -317,7 +374,7 @@ BOOL dfs_redirect(pstring pathname, connection_struct* conn, if (!conn || !pathname) return False; - parse_dfs_path(pathname, &dp); + parse_processed_dfs_path(pathname, &dp); /* if dfs pathname for a non-dfs share, convert to tcon-relative path and return false */ @@ -768,7 +825,7 @@ static BOOL junction_to_local_path(struct junction_map* jucn, char* path, return True; } -BOOL create_msdfs_link(struct junction_map* jucn, BOOL exists) +BOOL create_msdfs_link(struct junction_map *jucn, BOOL exists) { pstring path; pstring msdfs_link; -- cgit From c3d851fc7437cda798ca38faaad0e448097b46bc Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 10 Mar 2004 03:09:28 +0000 Subject: another type (This used to be commit 40634650d0489ebef17e090ef4544b772538b3dc) --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index b012c6c185..f00cf0c172 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -599,7 +599,7 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \ $(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \ $(PASSDB_OBJ) $(GROUPDB_OBJ) $(MSDFS_OBJ) \ $(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \ - $(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \ + $(LIB_SMBD_OBJ) $(AUTH_SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \ $(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \ $(RPC_LSA_DS_OBJ) $(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) \ $(RPC_SPOOLSS_OBJ) $(RPC_ECHO_OBJ) $(RPC_EPMAPPER_OBJ) \ -- cgit From faab4f3c27d994add8691817c2ec965e459fce96 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 10 Mar 2004 16:17:46 +0000 Subject: Don't pass DOM_SIDs around when pointers are enough. Volker (This used to be commit 27b27c28cd0421be3121e7f03c237df381c7ecb3) --- source3/groupdb/mapping.c | 8 ++++---- source3/passdb/util_sam_sid.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index bd387ee319..48bdfe2cd2 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -575,7 +575,7 @@ static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num) if (!string_to_sid(&sid, string_sid)) continue; - add_sid_to_array(sid, sids, num); + add_sid_to_array(&sid, sids, num); if (sids == NULL) return NT_STATUS_NO_MEMORY; @@ -694,7 +694,7 @@ static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num) if (is_foreign_alias_member(sid, &maps[i].sid)) { - add_sid_to_array(maps[i].sid, sids, num); + add_sid_to_array(&maps[i].sid, sids, num); if (sids == NULL) { SAFE_FREE(maps); @@ -710,7 +710,7 @@ static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num) for (i=0; i Date: Wed, 10 Mar 2004 16:32:58 +0000 Subject: Apply some const (This used to be commit e2696b81bb5e4d12281cf99dc50f91844ae51c2e) --- source3/libsmb/samlogon_cache.c | 4 ++-- source3/nsswitch/winbindd.h | 6 +++--- source3/nsswitch/winbindd_ads.c | 6 +++--- source3/nsswitch/winbindd_cache.c | 6 +++--- source3/nsswitch/winbindd_rpc.c | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 72c10007bf..4cd642c4e3 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -157,7 +157,7 @@ BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) free the user_info struct (malloc()'d memory) ***********************************************************************/ -NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, DOM_SID *user_sid) +NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user_sid) { NET_USER_INFO_3 *user = NULL; TDB_DATA data, key; @@ -218,7 +218,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, DOM_SID *user_sid) return user; } -BOOL netsamlogon_cache_have(DOM_SID *user_sid) +BOOL netsamlogon_cache_have(const DOM_SID *user_sid) { TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have"); NET_USER_INFO_3 *user = NULL; diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 340ea07733..cece2b40de 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -167,7 +167,7 @@ struct winbindd_methods { /* lookup user info for a given SID */ NTSTATUS (*query_user)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *user_sid, + const DOM_SID *user_sid, WINBIND_USERINFO *user_info); /* lookup all groups that a user is a member of. The backend @@ -175,13 +175,13 @@ struct winbindd_methods { function */ NTSTATUS (*lookup_usergroups)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *user_sid, + const DOM_SID *user_sid, uint32 *num_groups, DOM_SID ***user_gids); /* find all members of the group with the specified group_rid */ NTSTATUS (*lookup_groupmem)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *group_sid, + const DOM_SID *group_sid, uint32 *num_names, DOM_SID ***sid_mem, char ***names, uint32 **name_types); diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index e6b857f406..73c5af978c 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -390,7 +390,7 @@ failed: /* Lookup user information from a rid */ static NTSTATUS query_user(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *sid, + const DOM_SID *sid, WINBIND_USERINFO *info) { ADS_STRUCT *ads = NULL; @@ -561,7 +561,7 @@ done: /* Lookup groups a user is a member of. */ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *sid, + const DOM_SID *sid, uint32 *num_groups, DOM_SID ***user_gids) { ADS_STRUCT *ads = NULL; @@ -659,7 +659,7 @@ done: */ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *group_sid, uint32 *num_names, + const DOM_SID *group_sid, uint32 *num_names, DOM_SID ***sid_mem, char ***names, uint32 **name_types) { diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index 91834e476f..d684f6edfb 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -1039,7 +1039,7 @@ do_query: /* Lookup user information from a rid */ static NTSTATUS query_user(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *user_sid, + const DOM_SID *user_sid, WINBIND_USERINFO *info) { struct winbind_cache *cache = get_cache(domain); @@ -1102,7 +1102,7 @@ do_query: /* Lookup groups a user is a member of. */ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *user_sid, + const DOM_SID *user_sid, uint32 *num_groups, DOM_SID ***user_gids) { struct winbind_cache *cache = get_cache(domain); @@ -1185,7 +1185,7 @@ skip_save: static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *group_sid, uint32 *num_names, + const DOM_SID *group_sid, uint32 *num_names, DOM_SID ***sid_mem, char ***names, uint32 **name_types) { diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index d4428a2f59..25d5f64df6 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -366,7 +366,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, /* Lookup user information from a rid or username. */ static NTSTATUS query_user(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *user_sid, + const DOM_SID *user_sid, WINBIND_USERINFO *user_info) { CLI_POLICY_HND *hnd = NULL; @@ -465,7 +465,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain, /* Lookup groups a user is a member of. I wish Unix had a call like this! */ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *user_sid, + const DOM_SID *user_sid, uint32 *num_groups, DOM_SID ***user_grpsids) { CLI_POLICY_HND *hnd; @@ -571,7 +571,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, /* Lookup group membership given a rid. */ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *group_sid, uint32 *num_names, + const DOM_SID *group_sid, uint32 *num_names, DOM_SID ***sid_mem, char ***names, uint32 **name_types) { -- cgit From a70ccb3b20230c93ac14a5321f9650a10cfc8951 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 10 Mar 2004 16:40:41 +0000 Subject: Remove expanding sids from smbd, this will be done in winbindd. Volker (This used to be commit 67bb1d2338b0d5ba3f8a4754ff1479cd42cfb051) --- source3/auth/auth_util.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 871b399b86..b21b00ca8d 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -635,29 +635,6 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, return token; } -static void add_foreign_gids(uid_t uid, gid_t gid, - gid_t **groups, int *ngroups) -{ - int i, dom_groups; - DOM_SID sid; - - if (NT_STATUS_IS_OK(uid_to_sid(&sid, uid))) - add_foreign_gids_from_sid(&sid, groups, ngroups); - - if (NT_STATUS_IS_OK(gid_to_sid(&sid, gid))) - add_foreign_gids_from_sid(&sid, groups, ngroups); - - dom_groups = *ngroups; - - for (i=0; i Date: Wed, 10 Mar 2004 17:06:13 +0000 Subject: lsa_enumaccounts lists all SIDs that have been granted privileges. Simo, you should look at this. Change behaviour from listing all groups to listing only BUILTIN\Administrator Volker (This used to be commit 32d196e9bbf203855832da16eff3dee495679928) --- source3/rpc_server/srv_lsa_nt.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 1e3c6c2a9d..2d297d22f4 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -839,16 +839,17 @@ NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, L /*************************************************************************** _lsa_enum_accounts. + + This call lists all sids that have been granted privileges. I think it would + be ok not to return anything here, or only return BUILTIN\Administrators. ***************************************************************************/ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u) { + extern DOM_SID global_sid_Builtin_Administrators; struct lsa_info *handle; - GROUP_MAP *map=NULL; int num_entries=0; LSA_SID_ENUM *sids=&r_u->sids; - int i=0,j=0; - BOOL ret; if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) return NT_STATUS_INVALID_HANDLE; @@ -861,15 +862,8 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; - /* get the list of mapped groups (domain, local, builtin) */ - become_root(); - ret = pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED); - unbecome_root(); - if( !ret ) { - DEBUG(3,("_lsa_enum_accounts: enumeration of groups failed!\n")); - return NT_STATUS_OK; - } - + + num_entries = 1; if (q_u->enum_context >= num_entries) return NT_STATUS_NO_MORE_ENTRIES; @@ -878,19 +872,11 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU sids->sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, (num_entries-q_u->enum_context)*sizeof(DOM_SID2)); if (sids->ptr_sid==NULL || sids->sid==NULL) { - SAFE_FREE(map); return NT_STATUS_NO_MEMORY; } - for (i=q_u->enum_context, j=0; i Date: Thu, 11 Mar 2004 00:31:50 +0000 Subject: Fix processing of pathnames with embedded '\\' characters (0x5c) in CP932 character set. Because of the allowing of "broken conversions" for people who have broken iconv libraries we can't rely on the return from convert_string() to be valid - we must check errno instead. This is ripe for revisiting at some stage. I prefer adding a bool parameter to all convert_string_XX varients to specify if we will allow broken conversions or not. With "allow_broken_conversions" set to false we could then rely on the return from convert_string rather than checking errno. Jeremy. (This used to be commit 30c30c5ac53ec8f32a44d0b1b39cc99fe9844467) --- source3/smbd/reply.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 5bf8ca0a2d..dc9f0be401 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -45,7 +45,7 @@ extern BOOL global_encrypted_passwords_negotiated; set. ****************************************************************************/ -static NTSTATUS check_path_syntax(pstring destname, const pstring srcname) +NTSTATUS check_path_syntax(pstring destname, const pstring srcname) { char *d = destname; const char *s = srcname; @@ -122,12 +122,30 @@ static NTSTATUS check_path_syntax(pstring destname, const pstring srcname) */ uint16 ucs2_val; - if (convert_string(CH_UNIX, CH_UCS2, s, 1, &ucs2_val, 2) == 2) { + + /* + * We know the following will return 2 bytes. What + * we need to know was if errno was set. + * Note that if CH_UNIX is utf8 a string may be 3 + * bytes, but this is ok as mb utf8 characters don't + * contain embedded directory separators. We are really checking + * for mb UNIX asian characters like Japanese (SJIS) here. + * JRA. + */ + + errno = 0; + convert_string(CH_UNIX, CH_UCS2, s, 1, &ucs2_val, 2); + if (errno == 0) { ; - } else if (convert_string(CH_UNIX, CH_UCS2, s, 2, &ucs2_val, 2) == 2) { - *d++ = *s++; } else { - smb_panic("check_path_syntax: directory separator assumptions invalid !\n"); + errno = 0; + convert_string(CH_UNIX, CH_UCS2, s, 2, &ucs2_val, 2); + if (errno == 0) { + *d++ = *s++; + } else { + DEBUG(0,("check_path_syntax: directory separator assumptions invalid !\n")); + return NT_STATUS_INVALID_PARAMETER; + } } } /* Just copy the char (or the second byte of the mb char). */ -- cgit From ba76a6102d8bddf69515e503e73d1af0dd1a8d3c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Mar 2004 00:42:36 +0000 Subject: Ensure we use check_path_syntax() to pull out DFS paths. Jeremy (This used to be commit ebf82e2c14827c0a0edd8ee373ce5200f7b0b3b0) --- source3/msdfs/msdfs.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index 41f66ecd51..5af73356e0 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -65,11 +65,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp) DEBUG(10,("parse_dfs_path: servicename: %s\n",pdp->servicename)); /* rest is reqpath */ - pstrcpy(pdp->reqpath, p+1); - p = pdp->reqpath; - while ((p = strchr_m(p, '\\'))!=NULL) { - *p++ = '/'; - } + check_path_syntax(pdp->reqpath, p+1); DEBUG(10,("parse_dfs_path: rest of the path: %s\n",pdp->reqpath)); return True; @@ -115,8 +111,7 @@ static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path* pdp) DEBUG(10,("parse_processed_dfs_path: servicename: %s\n",pdp->servicename)); /* rest is reqpath */ - /* JRA. We should do a check_path_syntax here.... TOFIX ! */ - pstrcpy(pdp->reqpath, p+1); + check_path_syntax(pdp->reqpath, p+1); DEBUG(10,("parse_processed_dfs_path: rest of the path: %s\n",pdp->reqpath)); return True; -- cgit From b025b77df1f3ffbc5c350505f7f2d4d42ac00451 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 11 Mar 2004 14:52:35 +0000 Subject: BUG 1088: patch from SATOH Fumiyasu -- use strchr_m() for query_host (smbclient -L) (This used to be commit e7d2315e45df7e2e4e586a8fc4a32d6880e83e4f) --- source3/client/client.c | 48 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 3a189a13e7..2d640a5573 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2846,27 +2846,6 @@ static int do_message_op(void) } -/** - * Process "-L hostname" option. - * - * We don't actually do anything yet -- we just stash the name in a - * global variable and do the query when all options have been read. - **/ - -static void remember_query_host(const char *arg, - pstring query_host) -{ - char *slash; - - while (*arg == '\\' || *arg == '/') - arg++; - pstrcpy(query_host, arg); - if ((slash = strchr(query_host, '/')) - || (slash = strchr(query_host, '\\'))) { - *slash = 0; - } -} - /**************************************************************************** main program ****************************************************************************/ @@ -2961,7 +2940,7 @@ static void remember_query_host(const char *arg, break; case 'L': - remember_query_host(poptGetOptArg(pc), query_host); + pstrcpy(query_host, poptGetOptArg(pc)); break; case 't': pstrcpy(term_code, poptGetOptArg(pc)); @@ -3069,14 +3048,25 @@ static void remember_query_host(const char *arg, return do_tar_op(base_directory); } - if ((p=strchr_m(query_host,'#'))) { - *p = 0; - p++; - sscanf(p, "%x", &name_type); - } - if (*query_host) { - return do_host_query(query_host); + char *qhost = query_host; + char *slash; + + while (*qhost == '\\' || *qhost == '/') + qhost++; + + if ((slash = strchr_m(qhost, '/')) + || (slash = strchr_m(qhost, '\\'))) { + *slash = 0; + } + + if ((p=strchr_m(qhost, '#'))) { + *p = 0; + p++; + sscanf(p, "%x", &name_type); + } + + return do_host_query(qhost); } if (message) { -- cgit From 686fcfa61e5e7f0bc6adaa6dc0af2a269c5592a8 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 11 Mar 2004 15:14:48 +0000 Subject: add missing #ifdef HAVE_BICONV stuff (This used to be commit 5e831f48f0d15a02a3bc406a7dc5249a57ceec4f) --- source3/include/includes.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/include/includes.h b/source3/include/includes.h index c5a7b459be..dd93c813d3 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -392,6 +392,9 @@ #ifdef HAVE_GICONV #include #endif +#ifdef HAVE_BICONV +#include +#endif #endif #if HAVE_KRB5_H -- cgit From 77b180d401b1f431dd550a8498b83bdb24cd7325 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 11 Mar 2004 18:10:08 +0000 Subject: Merge from 3.0. Fix munged dial in pdb_ldap (This used to be commit 46544e957f00f71e3a49e3d90cd88b4cf1b33408) --- source3/include/smbldap.h | 5 +++- source3/lib/smbldap.c | 17 +++++++++--- source3/passdb/pdb_ldap.c | 70 +++++++++++++++++++++++------------------------ source3/sam/idmap_ldap.c | 16 +++++------ 4 files changed, 60 insertions(+), 48 deletions(-) diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 9ef66a14ef..2f71f971d9 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -120,7 +120,10 @@ void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing, LDAPMod ***mods, const char *attribute, const char *newval); BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry, - const char *attribute, pstring value); + const char *attribute, char *value, + int max_len); +BOOL smbldap_get_single_pstring (LDAP * ldap_struct, LDAPMessage * entry, + const char *attribute, pstring value); /** * Struct to keep the state for all the ldap stuff diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 3bd8b12f2d..1c3829c1ef 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -290,7 +290,8 @@ static BOOL fetch_ldap_pw(char **dn, char** pw) ******************************************************************/ BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry, - const char *attribute, pstring value) + const char *attribute, char *value, + int max_len) { char **values; @@ -305,7 +306,7 @@ static BOOL fetch_ldap_pw(char **dn, char** pw) return False; } - if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, sizeof(pstring)) == (size_t)-1) { + if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len) == (size_t)-1) { DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n", attribute, values[0])); ldap_value_free(values); @@ -319,6 +320,14 @@ static BOOL fetch_ldap_pw(char **dn, char** pw) return True; } + BOOL smbldap_get_single_pstring (LDAP * ldap_struct, LDAPMessage * entry, + const char *attribute, pstring value) +{ + return smbldap_get_single_attribute(ldap_struct, entry, + attribute, value, + sizeof(pstring)); +} + /************************************************************************ Routine to manage the LDAPMod structure array manage memory used by the array, by each struct, and values @@ -415,11 +424,11 @@ static BOOL fetch_ldap_pw(char **dn, char** pw) LDAPMod ***mods, const char *attribute, const char *newval) { - pstring oldval; + char oldval[2048]; /* current largest allowed value is mungeddial */ BOOL existed; if (existing != NULL) { - existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval); + existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval, sizeof(oldval)); } else { existed = False; *oldval = '\0'; diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index eefd302d42..0ebb63b3fb 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -368,13 +368,13 @@ static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state, } ldap_value_free(ldap_values); - if ( !smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if ( !smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_UNIX_HOME), homedir) ) { return False; } - if ( !smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if ( !smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_GIDNUMBER), temp) ) { return False; @@ -454,7 +454,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, return False; } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, "uid", username)) { + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, "uid", username)) { DEBUG(1, ("init_sam_from_ldap: No uid attribute found for this user!\n")); return False; } @@ -473,25 +473,25 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, /* deal with different attributes between the schema first */ if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) { - if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp)) { pdb_set_user_sid_from_string(sampass, temp, PDB_SET); } - if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_SID), temp)) { pdb_set_group_sid_from_string(sampass, temp, PDB_SET); } else { pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT); } } else { - if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp)) { user_rid = (uint32)atol(temp); pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_RID), temp)) { pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT); } else { @@ -539,7 +539,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, } #endif - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp)) { /* leave as default */ } else { @@ -547,7 +547,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp)) { /* leave as default */ } else { @@ -555,7 +555,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_logon_time(sampass, logon_time, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp)) { /* leave as default */ } else { @@ -563,7 +563,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_logoff_time(sampass, logoff_time, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp)) { /* leave as default */ } else { @@ -571,7 +571,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp)) { /* leave as default */ } else { @@ -579,7 +579,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp)) { /* leave as default */ } else { @@ -593,9 +593,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, * that fits your needs; using cn then displayName rather than 'userFullName' */ - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), fullname)) { - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_CN), fullname)) { /* leave as default */ } else { @@ -605,7 +605,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_fullname(sampass, fullname, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive)) { pdb_set_dir_drive( sampass, @@ -615,7 +615,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_dir_drive(sampass, dir_drive, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir)) { pdb_set_homedir( sampass, @@ -625,7 +625,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_homedir(sampass, homedir, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script)) { pdb_set_logon_script( sampass, @@ -635,7 +635,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_logon_script(sampass, logon_script, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path)) { pdb_set_profile_path( sampass, @@ -645,7 +645,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_profile_path(sampass, profile_path, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), acct_desc)) { /* leave as default */ @@ -653,7 +653,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_acct_desc(sampass, acct_desc, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), workstations)) { /* leave as default */; } else { @@ -661,7 +661,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, } if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, - get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), munged_dial)) { + get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), munged_dial, sizeof(munged_dial))) { /* leave as default */; } else { pdb_set_munged_dial(sampass, munged_dial, PDB_SET); @@ -673,7 +673,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, hours_len = 21; memset(hours, 0xff, hours_len); - if (!smbldap_get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp)) { /* leave as default */ } else { @@ -684,7 +684,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, ZERO_STRUCT(smblmpwd); } - if (!smbldap_get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp)) { /* leave as default */ } else { @@ -695,7 +695,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, ZERO_STRUCT(smbntpwd); } - if (!smbldap_get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp)) { acct_ctrl |= ACB_NORMAL; } else { @@ -712,7 +712,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, /* pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */ - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) { /* leave as default */ } else { @@ -720,7 +720,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_COUNT), temp)) { /* leave as default */ } else { @@ -1686,7 +1686,7 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state, return False; } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), temp)) { DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n", get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER))); @@ -1696,7 +1696,7 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state, map->gid = (gid_t)atol(temp); - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID), temp)) { DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n", get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID))); @@ -1708,7 +1708,7 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state, return False; } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp)) { DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n", get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE))); @@ -1722,10 +1722,10 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state, return False; } - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), temp)) { temp[0] = '\0'; - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp)) { DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \ @@ -1735,7 +1735,7 @@ for gidNumber(%lu)\n",(unsigned long)map->gid)); } fstrcpy(map->nt_name, temp); - if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), temp)) { temp[0] = '\0'; } @@ -2372,7 +2372,7 @@ and will risk BDCs having inconsistant SIDs\n")); return NT_STATUS_UNSUCCESSFUL; } - if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), domain_sid_string)) { BOOL found_sid; @@ -2395,7 +2395,7 @@ and will risk BDCs having inconsistant SIDs\n")); sid_copy(&ldap_state->domain_sid, &ldap_domain_sid); } - if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, + if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ALGORITHMIC_RID_BASE), alg_rid_base_string)) { alg_rid_base = (uint32)atol(alg_rid_base_string); diff --git a/source3/sam/idmap_ldap.c b/source3/sam/idmap_ldap.c index 55f4578448..2124fb6879 100644 --- a/source3/sam/idmap_ldap.c +++ b/source3/sam/idmap_ldap.c @@ -204,7 +204,7 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, algorithmic_rid_base. The other two are to avoid stomping on the different sets of algorithmic RIDs */ - if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry, + if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE), algorithmic_rid_base_string)) { @@ -224,7 +224,7 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, if (alg_rid_base > BASE_RID) { /* we have a non-default 'algorithmic rid base', so we have 'low' rids that we can allocate to new users */ - if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry, + if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_RID), old_rid_string)) { *rid = (uint32)atol(old_rid_string); @@ -250,14 +250,14 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, if (!next_rid) { /* not got one already */ switch (rid_type) { case USER_RID_TYPE: - if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry, + if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), old_rid_string)) { *rid = (uint32)atol(old_rid_string); } break; case GROUP_RID_TYPE: - if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry, + if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), old_rid_string)) { *rid = (uint32)atol(old_rid_string); @@ -297,7 +297,7 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, pstring domain_sid_string; int error = 0; - if (!smbldap_get_single_attribute(state->smbldap_state->ldap_struct, domain_result, + if (!smbldap_get_single_pstring(state->smbldap_state->ldap_struct, domain_result, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), domain_sid_string)) { ldap_mods_free(mods, True); @@ -420,7 +420,7 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type) } entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); - if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, type, id_str)) { + if (!smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, type, id_str)) { DEBUG(0,("ldap_allocate_id: %s attribute not found\n", type)); goto out; @@ -528,7 +528,7 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); - if ( !smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID, sid_str) ) + if ( !smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID, sid_str) ) goto out; if (!string_to_sid(sid, sid_str)) @@ -642,7 +642,7 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn, type)); - if ( smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, type, id_str) ) { + if ( smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, type, id_str) ) { if ( (*id_type & ID_USERID) ) id->uid = strtoul(id_str, NULL, 10); else -- cgit From 39c731347045dc345862d527871ae5b9a4619e74 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Mar 2004 22:59:58 +0000 Subject: Restore the contract on all convert_stringXX() interfaces. Add a "allow_bad_conv" boolean parameter that allows broken iconv conversions to work. Gets rid of the nasty errno checks in mangle_hash2 and check_path_syntax and allows correct return code checking. Jeremy. (This used to be commit 3b4fca7b7f410cb0f11322e22c8f26a662eff941) --- source3/lib/charcnv.c | 102 +++++++++++++++++++++++++++----------------- source3/lib/dprintf.c | 2 +- source3/lib/smbldap.c | 2 +- source3/lib/util_unistr.c | 4 +- source3/libsmb/climessage.c | 2 +- source3/smbd/mangle_hash2.c | 6 +-- source3/smbd/message.c | 2 +- source3/smbd/reply.c | 28 +++--------- source3/utils/ntlm_auth.c | 2 +- source3/web/cgi.c | 8 ++-- 10 files changed, 81 insertions(+), 77 deletions(-) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index f96d37bccc..751c0ad853 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -156,6 +156,7 @@ void init_iconv(void) * @param srclen length of the source string in bytes * @param dest pointer to destination string (multibyte or singlebyte) * @param destlen maximal length allowed for string + * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors) * @returns the number of bytes occupied in the destination * * Ensure the srclen contains the terminating zero. @@ -164,7 +165,7 @@ void init_iconv(void) static size_t convert_string_internal(charset_t from, charset_t to, void const *src, size_t srclen, - void *dest, size_t destlen) + void *dest, size_t destlen, BOOL allow_bad_conv) { size_t i_len, o_len; size_t retval; @@ -188,7 +189,7 @@ static size_t convert_string_internal(charset_t from, charset_t to, if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { if (!conv_silent) DEBUG(0,("convert_string_internal: Conversion not supported.\n")); - return 0; + return (size_t)-1; } i_len=srclen; @@ -204,7 +205,9 @@ static size_t convert_string_internal(charset_t from, charset_t to, reason="Incomplete multibyte sequence"; if (!conv_silent) DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf)); - goto use_as_is; + if (allow_bad_conv) + goto use_as_is; + break; case E2BIG: reason="No more room"; if (!conv_silent) @@ -219,7 +222,9 @@ static size_t convert_string_internal(charset_t from, charset_t to, reason="Illegal multibyte sequence"; if (!conv_silent) DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf)); - goto use_as_is; + if (allow_bad_conv) + goto use_as_is; + break; default: if (!conv_silent) DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf)); @@ -313,6 +318,7 @@ static size_t convert_string_internal(charset_t from, charset_t to, * @param srclen length of the source string in bytes, or -1 for nul terminated. * @param dest pointer to destination string (multibyte or singlebyte) * @param destlen maximal length allowed for string - *NEVER* -1. + * @param allow_bad_conv determines if a "best effort" conversion is acceptable (never returns errors) * @returns the number of bytes occupied in the destination * * Ensure the srclen contains the terminating zero. @@ -323,7 +329,7 @@ static size_t convert_string_internal(charset_t from, charset_t to, size_t convert_string(charset_t from, charset_t to, void const *src, size_t srclen, - void *dest, size_t destlen) + void *dest, size_t destlen, BOOL allow_bad_conv) { /* * NB. We deliberately don't do a strlen here if srclen == -1. @@ -361,7 +367,7 @@ size_t convert_string(charset_t from, charset_t to, #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS goto general_case; #else - return retval + convert_string_internal(from, to, p, slen, q, dlen); + return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv); #endif } } @@ -390,7 +396,7 @@ size_t convert_string(charset_t from, charset_t to, #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS goto general_case; #else - return retval + convert_string_internal(from, to, p, slen, q, dlen); + return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv); #endif } } @@ -419,7 +425,7 @@ size_t convert_string(charset_t from, charset_t to, #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS goto general_case; #else - return retval + convert_string_internal(from, to, p, slen, q, dlen); + return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv); #endif } } @@ -429,7 +435,7 @@ size_t convert_string(charset_t from, charset_t to, #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS general_case: #endif - return convert_string_internal(from, to, src, srclen, dest, destlen); + return convert_string_internal(from, to, src, srclen, dest, destlen, allow_bad_conv); } /** @@ -449,7 +455,7 @@ size_t convert_string(charset_t from, charset_t to, **/ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, - void const *src, size_t srclen, void **dest) + void const *src, size_t srclen, void **dest, BOOL allow_bad_conv) { size_t i_len, o_len, destlen = MAX(srclen, 512); size_t retval; @@ -471,7 +477,9 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { if (!conv_silent) DEBUG(0,("convert_string_allocate: Conversion not supported.\n")); - goto use_as_is; + if (allow_bad_conv) + goto use_as_is; + return (size_t)-1; } convert: @@ -515,14 +523,18 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, reason="Incomplete multibyte sequence"; if (!conv_silent) DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf)); - goto use_as_is; + if (allow_bad_conv) + goto use_as_is; + break; case E2BIG: goto convert; case EILSEQ: reason="Illegal multibyte sequence"; if (!conv_silent) DEBUG(3,("convert_string_allocate: Conversion error: %s(%s)\n",reason,inbuf)); - goto use_as_is; + if (allow_bad_conv) + goto use_as_is; + break; } if (!conv_silent) DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf)); @@ -633,12 +645,12 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, * @returns Size in bytes of the converted string; or -1 in case of error. **/ static size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, - void const *src, size_t srclen, void **dest) + void const *src, size_t srclen, void **dest, BOOL allow_bad_conv) { size_t dest_len; *dest = NULL; - dest_len=convert_string_allocate(ctx, from, to, src, srclen, dest); + dest_len=convert_string_allocate(ctx, from, to, src, srclen, dest, allow_bad_conv); if (dest_len == (size_t)-1) return (size_t)-1; if (*dest == NULL) @@ -652,7 +664,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) smb_ucs2_t *buffer; size = push_ucs2_allocate(&buffer, src); - if (size == -1) { + if (size == (size_t)-1) { smb_panic("failed to create UCS2 buffer"); } if (!strupper_w(buffer) && (dest == src)) { @@ -660,7 +672,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) return srclen; } - size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen); + size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen, True); free(buffer); return size; } @@ -696,15 +708,15 @@ char *strdup_upper(const char *s) /* MB case. */ size_t size; wpstring buffer; - size = convert_string(CH_UNIX, CH_UCS2, s, -1, buffer, sizeof(buffer)); - if (size == -1) { + size = convert_string(CH_UNIX, CH_UCS2, s, -1, buffer, sizeof(buffer), True); + if (size == (size_t)-1) { return NULL; } strupper_w(buffer); - size = convert_string(CH_UCS2, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer)); - if (size == -1) { + size = convert_string(CH_UCS2, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer), True); + if (size == (size_t)-1) { return NULL; } } @@ -718,15 +730,15 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) smb_ucs2_t *buffer = NULL; size = convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, srclen, - (void **) &buffer); - if (size == -1 || !buffer) { + (void **) &buffer, True); + if (size == (size_t)-1 || !buffer) { smb_panic("failed to create UCS2 buffer"); } if (!strlower_w(buffer) && (dest == src)) { SAFE_FREE(buffer); return srclen; } - size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen); + size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen, True); SAFE_FREE(buffer); return size; } @@ -751,7 +763,7 @@ char *strdup_lower(const char *s) size = pull_ucs2_allocate(&out_buffer, buffer); SAFE_FREE(buffer); - if (size == -1) { + if (size == (size_t)-1) { return NULL; } @@ -798,7 +810,7 @@ size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags) if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) src_len++; - return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len); + return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True); } size_t push_ascii_fstring(void *dest, const char *src) @@ -849,7 +861,10 @@ size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, } } - ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len); + ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, True); + if (ret == (size_t)-1) { + dest_len = 0; + } if (dest_len) dest[MIN(ret, dest_len-1)] = 0; @@ -895,6 +910,7 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_ { size_t len=0; size_t src_len; + size_t ret; /* treat a pstring as "unlimited" length */ if (dest_len == (size_t)-1) @@ -916,7 +932,12 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_ /* ucs2 is always a multiple of 2 bytes */ dest_len &= ~1; - len += convert_string(CH_UNIX, CH_UCS2, src, src_len, dest, dest_len); + ret = convert_string(CH_UNIX, CH_UCS2, src, src_len, dest, dest_len, True); + if (ret == (size_t)-1) { + return 0; + } + + len += ret; if (flags & STR_UPPER) { smb_ucs2_t *dest_ucs2 = dest; @@ -947,7 +968,7 @@ size_t push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src) size_t src_len = strlen(src)+1; *dest = NULL; - return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, (void **)dest); + return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, (void **)dest, True); } @@ -965,7 +986,7 @@ size_t push_ucs2_allocate(smb_ucs2_t **dest, const char *src) size_t src_len = strlen(src)+1; *dest = NULL; - return convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, src_len, (void **)dest); + return convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, src_len, (void **)dest, True); } /** @@ -996,7 +1017,7 @@ static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags) if (flags & STR_TERMINATE) src_len++; - return convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len); + return convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len, True); } size_t push_utf8_fstring(void *dest, const char *src) @@ -1017,7 +1038,7 @@ size_t push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src) size_t src_len = strlen(src)+1; *dest = NULL; - return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void**)dest); + return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void**)dest, True); } /** @@ -1033,7 +1054,7 @@ size_t push_utf8_allocate(char **dest, const char *src) size_t src_len = strlen(src)+1; *dest = NULL; - return convert_string_allocate(NULL, CH_UNIX, CH_UTF8, src, src_len, (void **)dest); + return convert_string_allocate(NULL, CH_UNIX, CH_UTF8, src, src_len, (void **)dest, True); } /** @@ -1074,8 +1095,11 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_ if (src_len != (size_t)-1) src_len &= ~1; - ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len); - + ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len, True); + if (ret == (size_t)-1) { + return 0; + } + if (src_len == (size_t)-1) src_len = ret*2; @@ -1109,7 +1133,7 @@ size_t pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src) { size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t); *dest = NULL; - return convert_string_talloc(ctx, CH_UCS2, CH_UNIX, src, src_len, (void **)dest); + return convert_string_talloc(ctx, CH_UCS2, CH_UNIX, src, src_len, (void **)dest, True); } /** @@ -1124,7 +1148,7 @@ size_t pull_ucs2_allocate(char **dest, const smb_ucs2_t *src) { size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t); *dest = NULL; - return convert_string_allocate(NULL, CH_UCS2, CH_UNIX, src, src_len, (void **)dest); + return convert_string_allocate(NULL, CH_UCS2, CH_UNIX, src, src_len, (void **)dest, True); } /** @@ -1139,7 +1163,7 @@ size_t pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src) { size_t src_len = strlen(src)+1; *dest = NULL; - return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest); + return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest, True); } /** @@ -1154,7 +1178,7 @@ size_t pull_utf8_allocate(char **dest, const char *src) { size_t src_len = strlen(src)+1; *dest = NULL; - return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, (void **)dest); + return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, (void **)dest, True); } /** diff --git a/source3/lib/dprintf.c b/source3/lib/dprintf.c index 70387bbd61..c62a1f41d1 100644 --- a/source3/lib/dprintf.c +++ b/source3/lib/dprintf.c @@ -59,7 +59,7 @@ again: SAFE_FREE(p); return -1; } - clen = convert_string(CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen); + clen = convert_string(CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen, True); if (clen >= maxlen) { /* it didn't fit - try a larger buffer */ diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 1c3829c1ef..c15ba51306 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -306,7 +306,7 @@ static BOOL fetch_ldap_pw(char **dn, char** pw) return False; } - if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len) == (size_t)-1) { + if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len, False) == (size_t)-1) { DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n", attribute, values[0])); ldap_value_free(values); diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index e90a824395..005f10a4c0 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -109,9 +109,9 @@ static int check_dos_char_slowly(smb_ucs2_t c) char buf[10]; smb_ucs2_t c2 = 0; int len1, len2; - len1 = convert_string(CH_UCS2, CH_DOS, &c, 2, buf, sizeof(buf)); + len1 = convert_string(CH_UCS2, CH_DOS, &c, 2, buf, sizeof(buf),False); if (len1 == 0) return 0; - len2 = convert_string(CH_DOS, CH_UCS2, buf, len1, &c2, 2); + len2 = convert_string(CH_DOS, CH_UCS2, buf, len1, &c2, 2,False); if (len2 != 2) return 0; return (c == c2); } diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 035088212c..8429ca4f41 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -87,7 +87,7 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) p = smb_buf(cli->outbuf); *p++ = 1; - if ((lendos = convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **) &msgdos)) < 0 || !msgdos) { + if ((lendos = (int)convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **) &msgdos, True)) < 0 || !msgdos) { DEBUG(3,("Conversion failed, sending message in UNIX charset\n")); SSVAL(p, 0, len); p += 2; memcpy(p, msg, len); diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c index 8dfa84d054..62087e7e59 100644 --- a/source3/smbd/mangle_hash2.c +++ b/source3/smbd/mangle_hash2.c @@ -453,17 +453,13 @@ static BOOL is_legal_name(const char *name) /* Possible start of mb character. */ char mbc[2]; /* - * We know the following will return 2 bytes. What - * we need to know was if errno was set. * Note that if CH_UNIX is utf8 a string may be 3 * bytes, but this is ok as mb utf8 characters don't * contain embedded ascii bytes. We are really checking * for mb UNIX asian characters like Japanese (SJIS) here. * JRA. */ - errno = 0; - convert_string(CH_UNIX, CH_UCS2, name, 2, mbc, 2); - if (!errno) { + if (convert_string(CH_UNIX, CH_UCS2, name, 2, mbc, 2, False) == 2) { /* Was a good mb string. */ name += 2; continue; diff --git a/source3/smbd/message.c b/source3/smbd/message.c index 88f833e468..f853a91475 100644 --- a/source3/smbd/message.c +++ b/source3/smbd/message.c @@ -64,7 +64,7 @@ static void msg_deliver(void) * Incoming message is in DOS codepage format. Convert to UNIX. */ - if ((len = convert_string_allocate(NULL,CH_DOS, CH_UNIX, msgbuf, msgpos, (void **) &msg)) < 0 || !msg) { + if ((len = (int)convert_string_allocate(NULL,CH_DOS, CH_UNIX, msgbuf, msgpos, (void **) &msg, True)) < 0 || !msg) { DEBUG(3,("Conversion failed, delivering message in DOS codepage format\n")); for (i = 0; i < msgpos;) { if (msgbuf[i] == '\r' && i < (msgpos-1) && msgbuf[i+1] == '\n') { diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index dc9f0be401..4a0c06f442 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -117,35 +117,19 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname) * conversion to unicode. If the one byte char converts then * it really is a directory separator following. Otherwise if * the two byte character converts (and it should or our assumption - * about character sets is broken and we panic) then copy both + * about character sets is broken and we return an error) then copy both * bytes as it's a MB character, not a directory separator. */ uint16 ucs2_val; - /* - * We know the following will return 2 bytes. What - * we need to know was if errno was set. - * Note that if CH_UNIX is utf8 a string may be 3 - * bytes, but this is ok as mb utf8 characters don't - * contain embedded directory separators. We are really checking - * for mb UNIX asian characters like Japanese (SJIS) here. - * JRA. - */ - - errno = 0; - convert_string(CH_UNIX, CH_UCS2, s, 1, &ucs2_val, 2); - if (errno == 0) { + if (convert_string(CH_UNIX, CH_UCS2, s, 1, &ucs2_val, 2, False) == 2) { ; + } else if (convert_string(CH_UNIX, CH_UCS2, s, 2, &ucs2_val, 2, False) == 2) { + *d++ = *s++; } else { - errno = 0; - convert_string(CH_UNIX, CH_UCS2, s, 2, &ucs2_val, 2); - if (errno == 0) { - *d++ = *s++; - } else { - DEBUG(0,("check_path_syntax: directory separator assumptions invalid !\n")); - return NT_STATUS_INVALID_PARAMETER; - } + DEBUG(0,("check_path_syntax: directory separator assumptions invalid !\n")); + return NT_STATUS_INVALID_PARAMETER; } } /* Just copy the char (or the second byte of the mb char). */ diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index d2a1547f77..ec0f404176 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1864,7 +1864,7 @@ static BOOL test_plaintext(enum ntlm_break break_which) if ((convert_string_allocate(NULL, CH_UNIX, CH_DOS, password, strlen(password)+1, - (void**)&lm_response.data)) == -1) { + (void**)&lm_response.data,True)) == -1) { DEBUG(0, ("push_ascii_allocate failed!\n")); exit(1); } diff --git a/source3/web/cgi.c b/source3/web/cgi.c index aac009893c..07b9f52ff7 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -203,13 +203,13 @@ void cgi_load_variables(void) convert_string(CH_DISPLAY, CH_UNIX, variables[i].name, -1, - dest, sizeof(dest)); + dest, sizeof(dest), True); free(variables[i].name); variables[i].name = strdup(dest); convert_string(CH_DISPLAY, CH_UNIX, variables[i].value, -1, - dest, sizeof(dest)); + dest, sizeof(dest), True); free(variables[i].value); variables[i].value = strdup(dest); } @@ -336,11 +336,11 @@ static BOOL cgi_handle_authorization(char *line) convert_string(CH_DISPLAY, CH_UNIX, line, -1, - user, sizeof(user)); + user, sizeof(user), True); convert_string(CH_DISPLAY, CH_UNIX, p+1, -1, - user_pass, sizeof(user_pass)); + user_pass, sizeof(user_pass), True); /* * Try and get the user from the UNIX password file. -- cgit From d1189b812172a98cda86d0c9615edbae50ec67a6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Mar 2004 23:02:52 +0000 Subject: Fix bug introduced by Jim (touche :-) :-) - use new smbldap_get_single_pstring call :-). Jeremy. (This used to be commit 3c9fd2bdee097394cb0d0b6683748835c6a2d3a0) --- source3/param/config_ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/param/config_ldap.c b/source3/param/config_ldap.c index 1413fe158c..fe4693fb58 100644 --- a/source3/param/config_ldap.c +++ b/source3/param/config_ldap.c @@ -109,13 +109,13 @@ static NTSTATUS parse_section( while (entry) { int o; - if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, "sambaOptionName", option_name)) { + if (!smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, "sambaOptionName", option_name)) { goto done; } option_value[0] = '\0'; for (o = 1; option_attr_list[o].name != NULL; o++) { - if (smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, option_attr_list[o].name, option_value)) { + if (smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, option_attr_list[o].name, option_value)) { break; } } @@ -198,7 +198,7 @@ static NTSTATUS ldap_config_load( entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); - if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, "description", attr_text)) { + if (!smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, "description", attr_text)) { DEBUG(0, ("ldap_config_load: no description field in %s object\n", LDAP_OBJ_SAMBA_CONFIG)); } @@ -237,7 +237,7 @@ static NTSTATUS ldap_config_load( if (!(temp = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, entry))) { goto done; } - if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, "sambaShareName", attr_text)) { + if (!smbldap_get_single_pstring(ldap_state.smbldap_state->ldap_struct, entry, "sambaShareName", attr_text)) { goto done; } share_dn[i] = talloc_strdup(mem_ctx, temp); -- cgit From d99a3d2a5ab7e6ac3a971b7b951fe4106a5f548c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Mar 2004 01:43:23 +0000 Subject: Allow msdfs symlink syntax to be more forgiving (it took me ages to remember what it was :-). Allow msdfs links to now look like UNC paths : eg. sym_link -> msdfs://server/share/path/in/share or : sym_link -> msdfs:\\server\share\path\in\share Jeremy. (This used to be commit 3c89393e2907e4a3318fb3e94a911cd35f16b4c2) --- source3/msdfs/msdfs.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index 5af73356e0..b77e2111bc 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -198,13 +198,21 @@ static BOOL parse_symlink(char* buf,struct referral** preflist, } for(i=0;i Date: Fri, 12 Mar 2004 11:29:13 +0000 Subject: Fix string overflow due to wrong size calculation (This used to be commit cf0285f3ea017d300d94e8c7f7042ae8ccc8f960) --- source3/modules/vfs_recycle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index 9b31f6afb9..1cb1cb327b 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -219,7 +219,7 @@ static BOOL recycle_create_dir(vfs_handle_struct *handle, const char *dname) ALLOC_CHECK(tmp_str, done); tok_str = tmp_str; - len = strlen(dname); + len = strlen(dname)+1; new_dir = (char *)malloc(len + 1); ALLOC_CHECK(new_dir, done); *new_dir = '\0'; -- cgit From 7d092f3cc4f8d2d158aead1d61b43ff85e908a3f Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Fri, 12 Mar 2004 12:58:49 +0000 Subject: Fix build after Jeremy -- yet another place where convert_string() wasn't updated (This used to be commit e117ed1db84b2447793ccea4036e225c4a552e1e) --- source3/torture/utable.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/torture/utable.c b/source3/torture/utable.c index 5d819cc6af..ba803a0da4 100644 --- a/source3/torture/utable.c +++ b/source3/torture/utable.c @@ -51,7 +51,7 @@ BOOL torture_utable(int dummy) p = fname+strlen(fname); len = convert_string(CH_UCS2, CH_UNIX, &c2, 2, - p, sizeof(fname)-strlen(fname)); + p, sizeof(fname)-strlen(fname), True); p[len] = 0; fstrcat(fname,"_a_long_extension"); @@ -108,7 +108,7 @@ static char *form_name(int c) len = convert_string(CH_UCS2, CH_UNIX, &c2, 2, - p, sizeof(fname)-strlen(fname)); + p, sizeof(fname)-strlen(fname), True); p[len] = 0; return fname; } -- cgit From c332ea64856342da6b3e767af7f048d4525313e3 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Fri, 12 Mar 2004 14:28:14 +0000 Subject: Fix problems with very long filenames in both smbd and smbclient. It appears that we pass filename through resolve_wildcards() as pstring and use fstring temporary buffer there. As result, a long filename in unix charset (UTF-8 by default) can easily expand over 255 bytes while Windows is able to send to us such names (e.g. Japanese name of ~190 mb chars) which we unable to process through this small fstring buffer. Tested with W2K and smbclient, Japanese and Cyrillics. (This used to be commit cc70a548f3c48a9503fd54d01896cc2499f5bbcd) --- source3/client/client.c | 74 ++++++++++++++++++++++++------------------------- source3/configure.in | 2 +- source3/smbd/reply.c | 28 ++++++++++++------- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 2d640a5573..214b787297 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -47,7 +47,7 @@ static int io_bufsize = 64512; static int name_type = 0x20; static int max_protocol = PROTOCOL_NT1; -static int process_tok(fstring tok); +static int process_tok(pstring tok); static int cmd_help(void); /* 30 second timeout on most commands */ @@ -284,7 +284,7 @@ static int do_cd(char *newdir) static int cmd_cd(void) { - fstring buf; + pstring buf; int rc = 0; if (next_token_nr(NULL,buf,NULL,sizeof(buf))) @@ -572,7 +572,7 @@ static int cmd_dir(void) { uint16 attribute = aDIR | aSYSTEM | aHIDDEN; pstring mask; - fstring buf; + pstring buf; char *p=buf; int rc; @@ -612,7 +612,7 @@ static int cmd_du(void) { uint16 attribute = aDIR | aSYSTEM | aHIDDEN; pstring mask; - fstring buf; + pstring buf; char *p=buf; int rc; @@ -866,13 +866,13 @@ static void do_mget(file_info *finfo) static int cmd_more(void) { - fstring rname,lname,pager_cmd; + pstring rname,lname,pager_cmd; char *pager; int fd; int rc = 0; - fstrcpy(rname,cur_dir); - fstrcat(rname,"\\"); + pstrcpy(rname,cur_dir); + pstrcat(rname,"\\"); slprintf(lname,sizeof(lname)-1, "%s/smbmore.XXXXXX",tmpdir()); fd = smb_mkstemp(lname); @@ -909,7 +909,7 @@ static int cmd_mget(void) { uint16 attribute = aSYSTEM | aHIDDEN; pstring mget_mask; - fstring buf; + pstring buf; char *p=buf; *mget_mask = 0; @@ -963,7 +963,7 @@ static BOOL do_mkdir(char *name) static BOOL do_altname(char *name) { - fstring altname; + pstring altname; if (!NT_STATUS_IS_OK(cli_qpathinfo_alt_name(cli, name, altname))) { d_printf("%s getting alt name for %s\n", cli_errstr(cli),name); @@ -993,7 +993,7 @@ static int cmd_quit(void) static int cmd_mkdir(void) { pstring mask; - fstring buf; + pstring buf; char *p=buf; pstrcpy(mask,cur_dir); @@ -1035,7 +1035,7 @@ static int cmd_mkdir(void) static int cmd_altname(void) { pstring name; - fstring buf; + pstring buf; char *p=buf; pstrcpy(name,cur_dir); @@ -1187,7 +1187,7 @@ static int cmd_put(void) { pstring lname; pstring rname; - fstring buf; + pstring buf; char *p=buf; pstrcpy(rname,cur_dir); @@ -1349,7 +1349,7 @@ static int file_find(struct file_list **list, const char *directory, static int cmd_mput(void) { - fstring buf; + pstring buf; char *p=buf; while (next_token_nr(NULL,p,NULL,sizeof(buf))) { @@ -1447,7 +1447,7 @@ static int do_cancel(int job) static int cmd_cancel(void) { - fstring buf; + pstring buf; int job; if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { @@ -1536,7 +1536,7 @@ static void do_del(file_info *finfo) static int cmd_del(void) { pstring mask; - fstring buf; + pstring buf; uint16 attribute = aSYSTEM | aHIDDEN; if (recurse) @@ -1561,7 +1561,7 @@ static int cmd_del(void) static int cmd_open(void) { pstring mask; - fstring buf; + pstring buf; pstrcpy(mask,cur_dir); @@ -1584,7 +1584,7 @@ static int cmd_open(void) static int cmd_rmdir(void) { pstring mask; - fstring buf; + pstring buf; pstrcpy(mask,cur_dir); @@ -1609,7 +1609,7 @@ static int cmd_rmdir(void) static int cmd_link(void) { pstring src,dest; - fstring buf,buf2; + pstring buf,buf2; if (!SERVER_HAS_UNIX_CIFS(cli)) { d_printf("Server doesn't support UNIX CIFS calls.\n"); @@ -1643,7 +1643,7 @@ static int cmd_link(void) static int cmd_symlink(void) { pstring src,dest; - fstring buf,buf2; + pstring buf,buf2; if (!SERVER_HAS_UNIX_CIFS(cli)) { d_printf("Server doesn't support UNIX CIFS calls.\n"); @@ -1679,7 +1679,7 @@ static int cmd_chmod(void) { pstring src; mode_t mode; - fstring buf, buf2; + pstring buf, buf2; if (!SERVER_HAS_UNIX_CIFS(cli)) { d_printf("Server doesn't support UNIX CIFS calls.\n"); @@ -1715,7 +1715,7 @@ static int cmd_chown(void) pstring src; uid_t uid; gid_t gid; - fstring buf, buf2, buf3; + pstring buf, buf2, buf3; if (!SERVER_HAS_UNIX_CIFS(cli)) { d_printf("Server doesn't support UNIX CIFS calls.\n"); @@ -1751,7 +1751,7 @@ static int cmd_chown(void) static int cmd_rename(void) { pstring src,dest; - fstring buf,buf2; + pstring buf,buf2; pstrcpy(src,cur_dir); pstrcpy(dest,cur_dir); @@ -1780,7 +1780,7 @@ static int cmd_rename(void) static int cmd_hardlink(void) { pstring src,dest; - fstring buf,buf2; + pstring buf,buf2; pstrcpy(src,cur_dir); pstrcpy(dest,cur_dir); @@ -1820,7 +1820,7 @@ static int cmd_prompt(void) static int cmd_newer(void) { - fstring buf; + pstring buf; BOOL ok; SMB_STRUCT_STAT sbuf; @@ -1847,7 +1847,7 @@ static int cmd_newer(void) static int cmd_archive(void) { - fstring buf; + pstring buf; if (next_token_nr(NULL,buf,NULL,sizeof(buf))) { archive_level = atoi(buf); @@ -1937,7 +1937,7 @@ static int cmd_printmode(void) static int cmd_lcd(void) { - fstring buf; + pstring buf; pstring d; if (next_token_nr(NULL,buf,NULL,sizeof(buf))) @@ -1982,7 +1982,7 @@ static int cmd_reput(void) { pstring local_name; pstring remote_name; - fstring buf; + pstring buf; char *p = buf; SMB_STRUCT_STAT st; @@ -2126,7 +2126,7 @@ static int cmd_vuid(void) static int cmd_logon(void) { pstring l_username, l_password; - fstring buf,buf2; + pstring buf,buf2; if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { d_printf("logon []\n"); @@ -2236,7 +2236,7 @@ static struct abbreviations. ******************************************************************/ -static int process_tok(fstring tok) +static int process_tok(pstring tok) { int i = 0, matches = 0; int cmd=0; @@ -2269,7 +2269,7 @@ static int process_tok(fstring tok) static int cmd_help(void) { int i=0,j; - fstring buf; + pstring buf; if (next_token_nr(NULL,buf,NULL,sizeof(buf))) { if ((i = process_tok(buf)) >= 0) @@ -2306,7 +2306,7 @@ static int process_command_string(char *cmd) while (cmd[0] != '\0') { char *p; - fstring tok; + pstring tok; int i; if ((p = strchr_m(cmd, ';')) == 0) { @@ -2569,8 +2569,8 @@ static void process_stdin(void) const char *ptr; while (1) { - fstring tok; - fstring the_prompt; + pstring tok; + pstring the_prompt; char *cline; pstring line; int i; @@ -2613,11 +2613,11 @@ static struct cli_state *do_connect(const char *server, const char *share) struct nmb_name called, calling; const char *server_n; struct in_addr ip; - fstring servicename; + pstring servicename; char *sharename; /* make a copy so we don't modify the global string 'service' */ - fstrcpy(servicename, share); + pstrcpy(servicename, share); sharename = servicename; if (*sharename == '\\') { server = sharename+2; @@ -2853,7 +2853,7 @@ static int do_message_op(void) int main(int argc,char *argv[]) { extern BOOL AllowDebugChange; - fstring base_directory; + pstring base_directory; int opt; pstring query_host; BOOL message = False; @@ -2971,7 +2971,7 @@ static int do_message_op(void) } break; case 'D': - fstrcpy(base_directory,poptGetOptArg(pc)); + pstrcpy(base_directory,poptGetOptArg(pc)); break; case 'g': grepable=True; diff --git a/source3/configure.in b/source3/configure.in index d07baf1210..6cb64e8d87 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -34,7 +34,7 @@ AC_ARG_WITH(fhs, logfilebase="\${VARDIR}/log/samba" privatedir="\${CONFIGDIR}/private" libdir="\${prefix}/lib/samba" - swatdir="\${LIBDIR}/samba/swat" + swatdir="\${prefix}/share/samba/swat" ;; esac]) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 4a0c06f442..aeac9e4c84 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3361,14 +3361,18 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, /******************************************************************* Resolve wildcards in a filename rename. + Note that name is in UNIX charset and thus potentially can be more + than fstring buffer (255 bytes) especially in default UTF-8 case. + Therefore, we use pstring inside and all calls should ensure that + name2 is at least pstring-long (they do already) ********************************************************************/ static BOOL resolve_wildcards(const char *name1, char *name2) { - fstring root1,root2; - fstring ext1,ext2; + pstring root1,root2; + pstring ext1,ext2; char *p,*p2, *pname1, *pname2; - int available_space; + int available_space, actual_space; pname1 = strrchr_m(name1,'/'); @@ -3377,21 +3381,21 @@ static BOOL resolve_wildcards(const char *name1, char *name2) if (!pname1 || !pname2) return(False); - fstrcpy(root1,pname1); - fstrcpy(root2,pname2); + pstrcpy(root1,pname1); + pstrcpy(root2,pname2); p = strrchr_m(root1,'.'); if (p) { *p = 0; - fstrcpy(ext1,p+1); + pstrcpy(ext1,p+1); } else { - fstrcpy(ext1,""); + pstrcpy(ext1,""); } p = strrchr_m(root2,'.'); if (p) { *p = 0; - fstrcpy(ext2,p+1); + pstrcpy(ext2,p+1); } else { - fstrcpy(ext2,""); + pstrcpy(ext2,""); } p = root1; @@ -3423,7 +3427,11 @@ static BOOL resolve_wildcards(const char *name1, char *name2) available_space = sizeof(pstring) - PTR_DIFF(pname2, name2); if (ext2[0]) { - snprintf(pname2, available_space - 1, "%s.%s", root2, ext2); + actual_space = snprintf(pname2, available_space - 1, "%s.%s", root2, ext2); + if (actual_space >= available_space - 1) { + DEBUG(1,("resolve_wildcards: can't fit resolved name into specified buffer (overrun by %d bytes)\n", + actual_space - available_space)); + } } else { pstrcpy_base(pname2, root2, name2); } -- cgit From 5aee4157de9273ed42fe8c384014319d9b362375 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Mar 2004 20:24:07 +0000 Subject: Fix from Robert.Dahlem@gmx.net (Robert Dahlem) for bugid #1048 when mangled names are turned off. Jeremy. (This used to be commit 11487e24666c7b3dd4b37f4ef8aec8f8a5bd5a6f) --- source3/smbd/trans2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 19269cbc6c..2f164dafa2 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -684,7 +684,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, * a Win2k client bug. JRA. */ memset(p,'\0',26); - if (!was_8_3) { + if (!was_8_3 && lp_manglednames(SNUM(conn))) { pstring mangled_name; pstrcpy(mangled_name, fname); mangle_map(mangled_name,True,True,SNUM(conn)); @@ -806,7 +806,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, * a Win2k client bug. JRA. */ memset(p,'\0',26); - if (!was_8_3) { + if (!was_8_3 && lp_manglednames(SNUM(conn))) { pstring mangled_name; pstrcpy(mangled_name, fname); mangle_map(mangled_name,True,True,SNUM(conn)); -- cgit From f17b47b7fdd41d4daf16545a177bab9aafb2b14f Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 12 Mar 2004 20:27:23 +0000 Subject: Bug report 1079 and fix both from Bert Driehuis. This is an odd corner case having to do with <1C> group names (DC names). <1C> group names are called (by MS) "Internet Special Groups", which means that Microsoft's WINS servers will attempt to handle these names in something approximating an RFC1001/1002 compliant manner. The problem being reported here is this: If an initial registration sent by one of the group members is lost (network error, whatever) then subsequent refreshes from that particular machine will also fail. This only happens if the name is already active (because of other group members). In most cases, we (and MS) handle refreshes as registrations if the name is not in the database. In this situation, we missed the corner case. Bert's fix adds an 'else if' that catches the situation in which a refresh for an unlisted IP of an active <1C> group name is received. The refresh is simply handled as a registration when this happens. [Note: Committing in HEAD. I am writing some tools to do registrations and refreshes so that I can test this. I don't have an NT Domain for testing so I'm going to have to fudge. This fix is small (I cleaned up some Debug messages and comments in addition to the fix) and if you want to test it with 3.0.x you can just copy the HEAD version into your 3.0.x tree and recompile.] (This used to be commit 8e52439f4ae9de84107e2d0e9f33f0d4e3c5945a) --- source3/nmbd/nmbd_winsserver.c | 116 +++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 38 deletions(-) diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c index 3694072420..aae1cf633f 100644 --- a/source3/nmbd/nmbd_winsserver.c +++ b/source3/nmbd/nmbd_winsserver.c @@ -440,8 +440,8 @@ static void send_wins_name_registration_response(int rcode, int ttl, struct pack Deal with a name refresh request to a WINS server. ************************************************************************/ -void wins_process_name_refresh_request(struct subnet_record *subrec, - struct packet_struct *p) +void wins_process_name_refresh_request( struct subnet_record *subrec, + struct packet_struct *p ) { struct nmb_packet *nmb = &p->packet.nmb; struct nmb_name *question = &nmb->question.question_name; @@ -453,28 +453,36 @@ void wins_process_name_refresh_request(struct subnet_record *subrec, struct in_addr from_ip; struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0"); - putip((char *)&from_ip,&nmb->additional->rdata[2]); + putip( (char *)&from_ip, &nmb->additional->rdata[2] ); if(bcast) { /* * We should only get unicast name refresh packets here. - * Anyone trying to refresh broadcast should not be going to a WINS - * server. Log an error here. + * Anyone trying to refresh broadcast should not be going + * to a WINS server. Log an error here. */ - - DEBUG(0,("wins_process_name_refresh_request: broadcast name refresh request \ -received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n", - nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name)); + if( DEBUGLVL( 0 ) ) { + dbgtext( "wins_process_name_refresh_request: " ); + dbgtext( "Broadcast name refresh request received " ); + dbgtext( "for name %s ", nmb_namestr(question) ); + dbgtext( "from IP %s ", inet_ntoa(from_ip) ); + dbgtext( "on subnet %s. ", subrec->subnet_name ); + dbgtext( "Error - Broadcasts should not be sent " ); + dbgtext( "to a WINS server\n" ); + } return; } - DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s \ -IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) )); + if( DEBUGLVL( 3 ) ) { + dbgtext( "wins_process_name_refresh_request: " ); + dbgtext( "Name refresh for name %s IP %s\n", + nmb_namestr(question), inet_ntoa(from_ip) ); + } /* * See if the name already exists. + * If not, handle it as a name registration and return. */ - namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME); /* @@ -482,48 +490,62 @@ IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) )); * treat it like a registration request. This allows us to recover * from errors (tridge) */ - if(namerec == NULL) { - DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \ -the name does not exist. Treating as registration.\n", nmb_namestr(question) )); + if( DEBUGLVL( 3 ) ) { + dbgtext( "wins_process_name_refresh_request: " ); + dbgtext( "Name refresh for name %s ", + nmb_namestr( question ) ); + dbgtext( "and the name does not exist. Treating " ); + dbgtext( "as registration.\n" ); + } wins_process_name_registration_request(subrec,p); return; } /* - * if the name is present but not active, - * simply remove it and treat the request - * as a registration + * if the name is present but not active, simply remove it + * and treat the refresh request as a registration & return. */ if (namerec != NULL && !WINS_STATE_ACTIVE(namerec)) { - DEBUG(5,("wins_process_name_refresh_request: Name (%s) in WINS was \ -not active - removing it.\n", nmb_namestr(question) )); + if( DEBUGLVL( 5 ) ) { + dbgtext( "wins_process_name_refresh_request: " ); + dbgtext( "Name (%s) in WINS ", nmb_namestr(question) ); + dbgtext( "was not active - removing it.\n" ); + } remove_name_from_namelist( subrec, namerec ); namerec = NULL; - wins_process_name_registration_request(subrec,p); + wins_process_name_registration_request( subrec, p ); return; } /* * Check that the group bits for the refreshing name and the - * name in our database match. + * name in our database match. If not, refuse the refresh. + * [crh: Why RFS_ERR instead of ACT_ERR? Is this what MS does?] */ - - if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) ) { - DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \ -does not match group bit in WINS for this name.\n", nmb_namestr(question), group ? "True" : "False" )); + if( (namerec != NULL) && + ( (group && !NAME_GROUP(namerec)) + || (!group && NAME_GROUP(namerec)) ) ) { + if( DEBUGLVL( 3 ) ) { + dbgtext( "wins_process_name_refresh_request: " ); + dbgtext( "Name %s ", nmb_namestr(question) ); + dbgtext( "group bit = %s does not match ", + group ? "True" : "False" ); + dbgtext( "group bit in WINS for this name.\n" ); + } send_wins_name_registration_response(RFS_ERR, 0, p); return; } /* - * For a unique name check that the person refreshing the name is one of the registered IP - * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c. - * Just return success for unique 0x1d refreshes. For normal group names update the ttl - * and return success. + * For a unique name check that the person refreshing the name is + * one of the registered IP addresses. If not - fail the refresh. + * Do the same for group names with a type of 0x1c. + * Just return success for unique 0x1d refreshes. For normal group + * names update the ttl and return success. */ - - if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip )) { + if( (!group || (group && (question->name_type == 0x1c))) + && find_ip_in_name_record(namerec, from_ip) ) { /* * Update the ttl. */ @@ -541,11 +563,26 @@ does not match group bit in WINS for this name.\n", nmb_namestr(question), group send_wins_name_registration_response(0, ttl, p); wins_hook("refresh", namerec, ttl); return; + } else if((group && (question->name_type == 0x1c))) { + /* + * Added by crh for bug #1079. + * Fix from Bert Driehuis + */ + if( DEBUGLVL( 3 ) ) { + dbgtext( "wins_process_name_refresh_request: " ); + dbgtext( "Name refresh for name %s, ", + nmb_namestr(question) ); + dbgtext( "but IP address %s ", inet_ntoa(from_ip) ); + dbgtext( "is not yet associated with " ); + dbgtext( "that name. Treating as registration.\n" ); + } + wins_process_name_registration_request(subrec,p); + return; } else if(group) { /* - * Normal groups are all registered with an IP address of 255.255.255.255 - * so we can't search for the IP address. - */ + * Normal groups are all registered with an IP address of + * 255.255.255.255 so we can't search for the IP address. + */ update_name_ttl(namerec, ttl); send_wins_name_registration_response(0, ttl, p); return; @@ -559,9 +596,12 @@ does not match group bit in WINS for this name.\n", nmb_namestr(question), group /* * Fail the refresh. */ - - DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \ -is IP is not known to the name.\n", nmb_namestr(question), inet_ntoa(from_ip) )); + if( DEBUGLVL( 3 ) ) { + dbgtext( "wins_process_name_refresh_request: " ); + dbgtext( "Name refresh for name %s with IP %s ", + nmb_namestr(question), inet_ntoa(from_ip) ); + dbgtext( "and is IP is not known to the name.\n" ); + } send_wins_name_registration_response(RFS_ERR, 0, p); return; } -- cgit From e4a01b392c518d3706d86d4938ac85707fe275e6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Mar 2004 00:28:55 +0000 Subject: First part of patch from moriyama@miraclelinux.com (MORIYAMA Masayuki) to fix up netbios names with mb strings. Includes reformat of libsmb/nmblib.c so it's readable. Jeremy. (This used to be commit beca3829d1140bf7c2e394993a02dff1f2cf7bbd) --- source3/include/smb.h | 3 +- source3/lib/charcnv.c | 30 +- source3/libsmb/namequery.c | 2 +- source3/libsmb/nmblib.c | 1659 +++++++++++++++++++++++--------------------- source3/smbd/reply.c | 2 +- 5 files changed, 887 insertions(+), 809 deletions(-) diff --git a/source3/include/smb.h b/source3/include/smb.h index 60be41b12e..835066e263 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1508,7 +1508,8 @@ struct cnotify_fns { #include "smb_macros.h" -typedef char nstring[16]; +#define MAX_NETBIOSNAME_LEN 16 +typedef char nstring[MAX_NETBIOSNAME_LEN]; /* A netbios name structure. */ struct nmb_name { diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 751c0ad853..7227a946bc 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -823,9 +823,37 @@ size_t push_ascii_pstring(void *dest, const char *src) return push_ascii(dest, src, sizeof(pstring), STR_TERMINATE); } +/******************************************************************** + Push an nstring - ensure null terminated. Written by + moriyama@miraclelinux.com (MORIYAMA Masayuki). +********************************************************************/ + size_t push_ascii_nstring(void *dest, const char *src) { - return push_ascii(dest, src, sizeof(nstring), STR_TERMINATE); + size_t i, buffer_len, dest_len; + smb_ucs2_t *buffer; + + buffer_len = push_ucs2_allocate(&buffer, src); + if (buffer_len == (size_t)-1) { + smb_panic("failed to create UCS2 buffer"); + } + + dest_len = 0; + for (i = 0; i < buffer_len; i++) { + unsigned char mb[10]; + /* Convert one smb_ucs2_t character at a time. */ + size_t mb_len = convert_string(CH_UCS2, CH_DOS, buffer+i, sizeof(smb_ucs2_t), mb, sizeof(mb), False); + if ((mb_len != (size_t)-1) && (dest_len + mb_len <= MAX_NETBIOSNAME_LEN - 1)) { + memcpy((char *)dest + dest_len, mb, mb_len); + dest_len += mb_len; + } else { + break; + } + } + ((char *)dest)[dest_len] = '\0'; + + SAFE_FREE(buffer); + return dest_len; } /** diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 8bde6d37ea..b6d1f8bda2 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -202,7 +202,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t if (i == count) goto done; - pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE); + pull_ascii_nstring(name, status[i].name); /* Store the result in the cache. */ /* but don't store an entry for 0x1c names here. Here we have diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ff38245435..cbe495cd95 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -39,274 +39,289 @@ static const struct opcode_names { }; /**************************************************************************** - * Lookup a nmb opcode name. - ****************************************************************************/ + Lookup a nmb opcode name. +****************************************************************************/ + static const char *lookup_opcode_name( int opcode ) { - const struct opcode_names *op_namep; - int i; - - for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { - op_namep = &nmb_header_opcode_names[i]; - if(opcode == op_namep->opcode) - return op_namep->nmb_opcode_name; - } - return ""; + const struct opcode_names *op_namep; + int i; + + for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { + op_namep = &nmb_header_opcode_names[i]; + if(opcode == op_namep->opcode) + return op_namep->nmb_opcode_name; + } + return ""; } /**************************************************************************** - print out a res_rec structure - ****************************************************************************/ + Print out a res_rec structure. +****************************************************************************/ + static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) { - int i, j; - - DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", - hdr, - nmb_namestr(&res->rr_name), - res->rr_type, - res->rr_class, - res->ttl ) ); - - if( res->rdlength == 0 || res->rdata == NULL ) - return; - - for (i = 0; i < res->rdlength; i+= 16) - { - DEBUGADD(4, (" %s %3x char ", hdr, i)); - - for (j = 0; j < 16; j++) - { - uchar x = res->rdata[i+j]; - if (x < 32 || x > 127) x = '.'; + int i, j; + + DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", + hdr, + nmb_namestr(&res->rr_name), + res->rr_type, + res->rr_class, + res->ttl ) ); + + if( res->rdlength == 0 || res->rdata == NULL ) + return; + + for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) { + DEBUGADD(4, (" %s %3x char ", hdr, i)); + + for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) { + unsigned char x = res->rdata[i+j]; + if (x < 32 || x > 127) + x = '.'; - if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%c", x)); - } + if (i+j >= res->rdlength) + break; + DEBUGADD(4, ("%c", x)); + } - DEBUGADD(4, (" hex ")); + DEBUGADD(4, (" hex ")); - for (j = 0; j < 16; j++) - { - if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j])); - } + for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) { + if (i+j >= res->rdlength) + break; + DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j])); + } - DEBUGADD(4, ("\n")); - } + DEBUGADD(4, ("\n")); + } } /**************************************************************************** - process a nmb packet - ****************************************************************************/ + Process a nmb packet. +****************************************************************************/ + void debug_nmb_packet(struct packet_struct *p) { - struct nmb_packet *nmb = &p->packet.nmb; - - if( DEBUGLVL( 4 ) ) - { - dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", - inet_ntoa(p->ip), p->port, - nmb->header.name_trn_id, - lookup_opcode_name(nmb->header.opcode), - nmb->header.opcode, - BOOLSTR(nmb->header.response) ); - dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", - BOOLSTR(nmb->header.nm_flags.bcast), - BOOLSTR(nmb->header.nm_flags.recursion_available), - BOOLSTR(nmb->header.nm_flags.recursion_desired), - BOOLSTR(nmb->header.nm_flags.trunc), - BOOLSTR(nmb->header.nm_flags.authoritative) ); - dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", - nmb->header.rcode, - nmb->header.qdcount, - nmb->header.ancount, - nmb->header.nscount, - nmb->header.arcount ); - } - - if (nmb->header.qdcount) - { - DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", - nmb_namestr(&nmb->question.question_name), - nmb->question.question_type, - nmb->question.question_class) ); - } - - if (nmb->answers && nmb->header.ancount) - { - debug_nmb_res_rec(nmb->answers,"answers"); - } - if (nmb->nsrecs && nmb->header.nscount) - { - debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); - } - if (nmb->additional && nmb->header.arcount) - { - debug_nmb_res_rec(nmb->additional,"additional"); - } + struct nmb_packet *nmb = &p->packet.nmb; + + if( DEBUGLVL( 4 ) ) { + dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + inet_ntoa(p->ip), p->port, + nmb->header.name_trn_id, + lookup_opcode_name(nmb->header.opcode), + nmb->header.opcode, + BOOLSTR(nmb->header.response) ); + dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + BOOLSTR(nmb->header.nm_flags.bcast), + BOOLSTR(nmb->header.nm_flags.recursion_available), + BOOLSTR(nmb->header.nm_flags.recursion_desired), + BOOLSTR(nmb->header.nm_flags.trunc), + BOOLSTR(nmb->header.nm_flags.authoritative) ); + dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + nmb->header.rcode, + nmb->header.qdcount, + nmb->header.ancount, + nmb->header.nscount, + nmb->header.arcount ); + } + + if (nmb->header.qdcount) { + DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", + nmb_namestr(&nmb->question.question_name), + nmb->question.question_type, + nmb->question.question_class) ); + } + + if (nmb->answers && nmb->header.ancount) { + debug_nmb_res_rec(nmb->answers,"answers"); + } + if (nmb->nsrecs && nmb->header.nscount) { + debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); + } + if (nmb->additional && nmb->header.arcount) { + debug_nmb_res_rec(nmb->additional,"additional"); + } } /******************************************************************* - handle "compressed" name pointers - ******************************************************************/ -static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length, + Handle "compressed" name pointers. +******************************************************************/ + +static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, BOOL *got_pointer,int *ret) { - int loop_count=0; + int loop_count=0; - while ((ubuf[*offset] & 0xC0) == 0xC0) { - if (!*got_pointer) (*ret) += 2; - (*got_pointer)=True; - (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; - if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { - return(False); - } - } - return(True); + while ((ubuf[*offset] & 0xC0) == 0xC0) { + if (!*got_pointer) + (*ret) += 2; + (*got_pointer)=True; + (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; + if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { + return(False); + } + } + return(True); } /******************************************************************* - parse a nmb name from "compressed" format to something readable - return the space taken by the name, or 0 if the name is invalid - ******************************************************************/ + Parse a nmb name from "compressed" format to something readable + return the space taken by the name, or 0 if the name is invalid +******************************************************************/ + static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) { - int m,n=0; - uchar *ubuf = (uchar *)inbuf; - int ret = 0; - BOOL got_pointer=False; - int loop_count=0; - int offset = ofs; - - if (length - offset < 2) - return(0); - - /* handle initial name pointers */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) - return(0); + int m,n=0; + unsigned char *ubuf = (unsigned char *)inbuf; + int ret = 0; + BOOL got_pointer=False; + int loop_count=0; + int offset = ofs; + + if (length - offset < 2) + return(0); + + /* handle initial name pointers */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); - m = ubuf[offset]; - - if (!m) - return(0); - if ((m & 0xC0) || offset+m+2 > length) - return(0); - - memset((char *)name,'\0',sizeof(*name)); - - /* the "compressed" part */ - if (!got_pointer) - ret += m + 2; - offset++; - while (m > 0) { - uchar c1,c2; - c1 = ubuf[offset++]-'A'; - c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) - return(0); - name->name[n++] = (c1<<4) | c2; - m -= 2; - } - name->name[n] = 0; - - if (n==16) { - /* parse out the name type, - its always in the 16th byte of the name */ - name->name_type = ((uchar)name->name[15]) & 0xff; + m = ubuf[offset]; + + if (!m) + return(0); + if ((m & 0xC0) || offset+m+2 > length) + return(0); + + memset((char *)name,'\0',sizeof(*name)); + + /* the "compressed" part */ + if (!got_pointer) + ret += m + 2; + offset++; + while (m > 0) { + unsigned char c1,c2; + c1 = ubuf[offset++]-'A'; + c2 = ubuf[offset++]-'A'; + if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) + return(0); + name->name[n++] = (c1<<4) | c2; + m -= 2; + } + name->name[n] = 0; + + if (n==MAX_NETBIOSNAME_LEN) { + /* parse out the name type, its always in the 16th byte of the name */ + name->name_type = ((unsigned char)name->name[15]) & 0xff; - /* remove trailing spaces */ - name->name[15] = 0; - n = 14; - while (n && name->name[n]==' ') - name->name[n--] = 0; - } - - /* now the domain parts (if any) */ - n = 0; - while (ubuf[offset]) { - /* we can have pointers within the domain part as well */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) - return(0); - - m = ubuf[offset]; - /* - * Don't allow null domain parts. - */ - if (!m) - return(0); - if (!got_pointer) - ret += m+1; - if (n) - name->scope[n++] = '.'; - if (m+2+offset>length || n+m+1>sizeof(name->scope)) - return(0); - offset++; - while (m--) - name->scope[n++] = (char)ubuf[offset++]; - - /* - * Watch for malicious loops. - */ - if (loop_count++ == 10) - return 0; - } - name->scope[n++] = 0; - - return(ret); + /* remove trailing spaces */ + name->name[15] = 0; + n = 14; + while (n && name->name[n]==' ') + name->name[n--] = 0; + } + + /* now the domain parts (if any) */ + n = 0; + while (ubuf[offset]) { + /* we can have pointers within the domain part as well */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); + + m = ubuf[offset]; + /* + * Don't allow null domain parts. + */ + if (!m) + return(0); + if (!got_pointer) + ret += m+1; + if (n) + name->scope[n++] = '.'; + if (m+2+offset>length || n+m+1>sizeof(name->scope)) + return(0); + offset++; + while (m--) + name->scope[n++] = (char)ubuf[offset++]; + + /* + * Watch for malicious loops. + */ + if (loop_count++ == 10) + return 0; + } + name->scope[n++] = 0; + + return(ret); } +/**************************************************************************** + Put a netbios name, padding(s) and a name type into a 16 character buffer. + name is already in DOS charset. + [15 bytes name + padding][1 byte name type]. +****************************************************************************/ + +static void put_name(char *dest, const char *name, int pad, unsigned int name_type) +{ + size_t len = strlen(name); + + memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1); + if (len < MAX_NETBIOSNAME_LEN - 1) { + memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len); + } + dest[MAX_NETBIOSNAME_LEN - 1] = name_type; +} /******************************************************************* - put a compressed nmb name into a buffer. return the length of the - compressed name + Put a compressed nmb name into a buffer. Return the length of the + compressed name. + + Compressed names are really weird. The "compression" doubles the + size. The idea is that it also means that compressed names conform + to the doman name system. See RFC1002. +******************************************************************/ - compressed names are really weird. The "compression" doubles the - size. The idea is that it also means that compressed names conform - to the doman name system. See RFC1002. - ******************************************************************/ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) { - int ret,m; - fstring buf1; - char *p; - - if (strcmp(name->name,"*") == 0) { - /* special case for wildcard name */ - memset(buf1,'\0',20); - buf1[0] = '*'; - buf1[15] = name->name_type; - } else { - slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type); - } - - buf[offset] = 0x20; - - ret = 34; - - for (m=0;m<16;m++) { - buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); - buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); - } - offset += 33; - - buf[offset] = 0; - - if (name->scope[0]) { - /* XXXX this scope handling needs testing */ - ret += strlen(name->scope) + 1; - safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); + int ret,m; + fstring buf1; + char *p; + + if (strcmp(name->name,"*") == 0) { + /* special case for wildcard name */ + put_name(buf1, "*", '\0', name->name_type); + } else { + put_name(buf1, name->name, ' ', name->name_type); + } + + buf[offset] = 0x20; + + ret = 34; + + for (m=0;m>4)&0xF); + buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); + } + offset += 33; + + buf[offset] = 0; + + if (name->scope[0]) { + /* XXXX this scope handling needs testing */ + ret += strlen(name->scope) + 1; + safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); - p = &buf[offset+1]; - while ((p = strchr_m(p,'.'))) { - buf[offset] = PTR_DIFF(p,&buf[offset+1]); - offset += (buf[offset] + 1); - p = &buf[offset+1]; - } - buf[offset] = strlen(&buf[offset+1]); - } - - return(ret); + p = &buf[offset+1]; + while ((p = strchr_m(p,'.'))) { + buf[offset] = PTR_DIFF(p,&buf[offset+1]); + offset += (buf[offset] + 1); + p = &buf[offset+1]; + } + buf[offset] = strlen(&buf[offset+1]); + } + + return(ret); } /******************************************************************* @@ -331,336 +346,347 @@ char *nmb_namestr(struct nmb_name *n) } /******************************************************************* - allocate and parse some resource records - ******************************************************************/ + Allocate and parse some resource records. +******************************************************************/ + static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, struct res_rec **recs, int count) { - int i; - *recs = (struct res_rec *)malloc(sizeof(**recs)*count); - if (!*recs) return(False); - - memset((char *)*recs,'\0',sizeof(**recs)*count); - - for (i=0;i length) { - SAFE_FREE(*recs); - return(False); - } - (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); - (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); - (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); - (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); - (*offset) += 10; - if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || - (*offset)+(*recs)[i].rdlength > length) { - SAFE_FREE(*recs); - return(False); - } - memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); - (*offset) += (*recs)[i].rdlength; - } - return(True); + int i; + + *recs = (struct res_rec *)malloc(sizeof(**recs)*count); + if (!*recs) + return(False); + + memset((char *)*recs,'\0',sizeof(**recs)*count); + + for (i=0;i length) { + SAFE_FREE(*recs); + return(False); + } + (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); + (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); + (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); + (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); + (*offset) += 10; + if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || + (*offset)+(*recs)[i].rdlength > length) { + SAFE_FREE(*recs); + return(False); + } + memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); + (*offset) += (*recs)[i].rdlength; + } + return(True); } /******************************************************************* - put a resource record into a packet - ******************************************************************/ + Put a resource record into a packet. +******************************************************************/ + static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) { - int ret=0; - int i; - - for (i=0;i> 8) & 0xFF)); - buf[offset+1] = (ptr_offset & 0xFF); - offset += 2; - ret += 2; - RSSVAL(buf,offset,rec->rr_type); - RSSVAL(buf,offset+2,rec->rr_class); - RSIVAL(buf,offset+4,rec->ttl); - RSSVAL(buf,offset+8,rec->rdlength); - memcpy(buf+offset+10,rec->rdata,rec->rdlength); - offset += 10+rec->rdlength; - ret += 10+rec->rdlength; + int ret=0; + buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); + buf[offset+1] = (ptr_offset & 0xFF); + offset += 2; + ret += 2; + RSSVAL(buf,offset,rec->rr_type); + RSSVAL(buf,offset+2,rec->rr_class); + RSIVAL(buf,offset+4,rec->ttl); + RSSVAL(buf,offset+8,rec->rdlength); + memcpy(buf+offset+10,rec->rdata,rec->rdlength); + offset += 10+rec->rdlength; + ret += 10+rec->rdlength; - return(ret); + return(ret); } /******************************************************************* - parse a dgram packet. Return False if the packet can't be parsed - or is invalid for some reason, True otherwise + Parse a dgram packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise. + + This is documented in section 4.4.1 of RFC1002. +******************************************************************/ - this is documented in section 4.4.1 of RFC1002 - ******************************************************************/ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) { - int offset; - int flags; - - memset((char *)dgram,'\0',sizeof(*dgram)); - - if (length < 14) return(False); - - dgram->header.msg_type = CVAL(inbuf,0); - flags = CVAL(inbuf,1); - dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); - if (flags & 1) dgram->header.flags.more = True; - if (flags & 2) dgram->header.flags.first = True; - dgram->header.dgm_id = RSVAL(inbuf,2); - putip((char *)&dgram->header.source_ip,inbuf+4); - dgram->header.source_port = RSVAL(inbuf,8); - dgram->header.dgm_length = RSVAL(inbuf,10); - dgram->header.packet_offset = RSVAL(inbuf,12); - - offset = 14; - - if (dgram->header.msg_type == 0x10 || - dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); - offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); - } + int offset; + int flags; + + memset((char *)dgram,'\0',sizeof(*dgram)); + + if (length < 14) + return(False); + + dgram->header.msg_type = CVAL(inbuf,0); + flags = CVAL(inbuf,1); + dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); + if (flags & 1) + dgram->header.flags.more = True; + if (flags & 2) + dgram->header.flags.first = True; + dgram->header.dgm_id = RSVAL(inbuf,2); + putip((char *)&dgram->header.source_ip,inbuf+4); + dgram->header.source_port = RSVAL(inbuf,8); + dgram->header.dgm_length = RSVAL(inbuf,10); + dgram->header.packet_offset = RSVAL(inbuf,12); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); + offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); + } - if (offset >= length || (length-offset > sizeof(dgram->data))) - return(False); + if (offset >= length || (length-offset > sizeof(dgram->data))) + return(False); - dgram->datasize = length-offset; - memcpy(dgram->data,inbuf+offset,dgram->datasize); + dgram->datasize = length-offset; + memcpy(dgram->data,inbuf+offset,dgram->datasize); - return(True); + return(True); } - /******************************************************************* - parse a nmb packet. Return False if the packet can't be parsed - or is invalid for some reason, True otherwise - ******************************************************************/ + Parse a nmb packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise. +******************************************************************/ + static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) { - int nm_flags,offset; - - memset((char *)nmb,'\0',sizeof(*nmb)); - - if (length < 12) return(False); - - /* parse the header */ - nmb->header.name_trn_id = RSVAL(inbuf,0); - - DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); - - nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; - nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; - nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); - nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; - nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; - nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; - nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; - nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; - nmb->header.rcode = CVAL(inbuf,3) & 0xF; - nmb->header.qdcount = RSVAL(inbuf,4); - nmb->header.ancount = RSVAL(inbuf,6); - nmb->header.nscount = RSVAL(inbuf,8); - nmb->header.arcount = RSVAL(inbuf,10); + int nm_flags,offset; + + memset((char *)nmb,'\0',sizeof(*nmb)); + + if (length < 12) + return(False); + + /* parse the header */ + nmb->header.name_trn_id = RSVAL(inbuf,0); + + DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); + + nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; + nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; + nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); + nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; + nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; + nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; + nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; + nmb->header.rcode = CVAL(inbuf,3) & 0xF; + nmb->header.qdcount = RSVAL(inbuf,4); + nmb->header.ancount = RSVAL(inbuf,6); + nmb->header.nscount = RSVAL(inbuf,8); + nmb->header.arcount = RSVAL(inbuf,10); - if (nmb->header.qdcount) { - offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); - if (!offset) return(False); - - if (length - (12+offset) < 4) return(False); - nmb->question.question_type = RSVAL(inbuf,12+offset); - nmb->question.question_class = RSVAL(inbuf,12+offset+2); - - offset += 12+4; - } else { - offset = 12; - } - - /* and any resource records */ - if (nmb->header.ancount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, - nmb->header.ancount)) - return(False); - - if (nmb->header.nscount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, - nmb->header.nscount)) - return(False); + if (nmb->header.qdcount) { + offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); + if (!offset) + return(False); + + if (length - (12+offset) < 4) + return(False); + nmb->question.question_type = RSVAL(inbuf,12+offset); + nmb->question.question_class = RSVAL(inbuf,12+offset+2); + + offset += 12+4; + } else { + offset = 12; + } + + /* and any resource records */ + if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, + nmb->header.ancount)) + return(False); + + if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, + nmb->header.nscount)) + return(False); - if (nmb->header.arcount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, - nmb->header.arcount)) - return(False); + if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, + nmb->header.arcount)) + return(False); - return(True); + return(True); } /******************************************************************* - 'Copy constructor' for an nmb packet - ******************************************************************/ + 'Copy constructor' for an nmb packet. +******************************************************************/ + static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) { - struct nmb_packet *nmb; - struct nmb_packet *copy_nmb; - struct packet_struct *pkt_copy; - - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) - { - DEBUG(0,("copy_nmb_packet: malloc fail.\n")); - return NULL; - } - - /* Structure copy of entire thing. */ - - *pkt_copy = *packet; - - /* Ensure this copy is not locked. */ - pkt_copy->locked = False; - - /* Ensure this copy has no resource records. */ - nmb = &packet->packet.nmb; - copy_nmb = &pkt_copy->packet.nmb; - - copy_nmb->answers = NULL; - copy_nmb->nsrecs = NULL; - copy_nmb->additional = NULL; - - /* Now copy any resource records. */ - - if (nmb->answers) - { - if((copy_nmb->answers = (struct res_rec *) - malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->answers, (char *)nmb->answers, - nmb->header.ancount * sizeof(struct res_rec)); - } - if (nmb->nsrecs) - { - if((copy_nmb->nsrecs = (struct res_rec *) - malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, - nmb->header.nscount * sizeof(struct res_rec)); - } - if (nmb->additional) - { - if((copy_nmb->additional = (struct res_rec *) - malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->additional, (char *)nmb->additional, - nmb->header.arcount * sizeof(struct res_rec)); - } - - return pkt_copy; - -free_and_exit: - - SAFE_FREE(copy_nmb->answers); - SAFE_FREE(copy_nmb->nsrecs); - SAFE_FREE(copy_nmb->additional); - SAFE_FREE(pkt_copy); - - DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); - return NULL; + struct nmb_packet *nmb; + struct nmb_packet *copy_nmb; + struct packet_struct *pkt_copy; + + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) { + DEBUG(0,("copy_nmb_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* Ensure this copy has no resource records. */ + nmb = &packet->packet.nmb; + copy_nmb = &pkt_copy->packet.nmb; + + copy_nmb->answers = NULL; + copy_nmb->nsrecs = NULL; + copy_nmb->additional = NULL; + + /* Now copy any resource records. */ + + if (nmb->answers) { + if((copy_nmb->answers = (struct res_rec *) + malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->answers, (char *)nmb->answers, + nmb->header.ancount * sizeof(struct res_rec)); + } + if (nmb->nsrecs) { + if((copy_nmb->nsrecs = (struct res_rec *) + malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, + nmb->header.nscount * sizeof(struct res_rec)); + } + if (nmb->additional) { + if((copy_nmb->additional = (struct res_rec *) + malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->additional, (char *)nmb->additional, + nmb->header.arcount * sizeof(struct res_rec)); + } + + return pkt_copy; + + free_and_exit: + + SAFE_FREE(copy_nmb->answers); + SAFE_FREE(copy_nmb->nsrecs); + SAFE_FREE(copy_nmb->additional); + SAFE_FREE(pkt_copy); + + DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); + return NULL; } /******************************************************************* - 'Copy constructor' for a dgram packet - ******************************************************************/ + 'Copy constructor' for a dgram packet. +******************************************************************/ + static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) { - struct packet_struct *pkt_copy; + struct packet_struct *pkt_copy; - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) - { - DEBUG(0,("copy_dgram_packet: malloc fail.\n")); - return NULL; - } + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) { + DEBUG(0,("copy_dgram_packet: malloc fail.\n")); + return NULL; + } - /* Structure copy of entire thing. */ + /* Structure copy of entire thing. */ - *pkt_copy = *packet; + *pkt_copy = *packet; - /* Ensure this copy is not locked. */ - pkt_copy->locked = False; + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; - /* There are no additional pointers in a dgram packet, - we are finished. */ - return pkt_copy; + /* There are no additional pointers in a dgram packet, + we are finished. */ + return pkt_copy; } /******************************************************************* - 'Copy constructor' for a generic packet - ******************************************************************/ + 'Copy constructor' for a generic packet. +******************************************************************/ + struct packet_struct *copy_packet(struct packet_struct *packet) { - if(packet->packet_type == NMB_PACKET) - return copy_nmb_packet(packet); - else if (packet->packet_type == DGRAM_PACKET) - return copy_dgram_packet(packet); - return NULL; + if(packet->packet_type == NMB_PACKET) + return copy_nmb_packet(packet); + else if (packet->packet_type == DGRAM_PACKET) + return copy_dgram_packet(packet); + return NULL; } /******************************************************************* - free up any resources associated with an nmb packet - ******************************************************************/ + Free up any resources associated with an nmb packet. +******************************************************************/ + static void free_nmb_packet(struct nmb_packet *nmb) { - SAFE_FREE(nmb->answers); - SAFE_FREE(nmb->nsrecs); - SAFE_FREE(nmb->additional); + SAFE_FREE(nmb->answers); + SAFE_FREE(nmb->nsrecs); + SAFE_FREE(nmb->additional); } /******************************************************************* - free up any resources associated with a dgram packet - ******************************************************************/ + Free up any resources associated with a dgram packet. +******************************************************************/ + static void free_dgram_packet(struct dgram_packet *nmb) { - /* We have nothing to do for a dgram packet. */ + /* We have nothing to do for a dgram packet. */ } /******************************************************************* - free up any resources associated with a packet - ******************************************************************/ + Free up any resources associated with a packet. +******************************************************************/ + void free_packet(struct packet_struct *packet) { - if (packet->locked) - return; - if (packet->packet_type == NMB_PACKET) - free_nmb_packet(&packet->packet.nmb); - else if (packet->packet_type == DGRAM_PACKET) - free_dgram_packet(&packet->packet.dgram); - ZERO_STRUCTPN(packet); - SAFE_FREE(packet); + if (packet->locked) + return; + if (packet->packet_type == NMB_PACKET) + free_nmb_packet(&packet->packet.nmb); + else if (packet->packet_type == DGRAM_PACKET) + free_dgram_packet(&packet->packet.dgram); + ZERO_STRUCTPN(packet); + SAFE_FREE(packet); } /******************************************************************* -parse a packet buffer into a packet structure - ******************************************************************/ + Parse a packet buffer into a packet structure. +******************************************************************/ + struct packet_struct *parse_packet(char *buf,int length, enum packet_type packet_type) { @@ -670,7 +696,8 @@ struct packet_struct *parse_packet(char *buf,int length, BOOL ok=False; p = (struct packet_struct *)malloc(sizeof(*p)); - if (!p) return(NULL); + if (!p) + return(NULL); p->next = NULL; p->prev = NULL; @@ -699,9 +726,10 @@ struct packet_struct *parse_packet(char *buf,int length, } /******************************************************************* - read a packet from a socket and parse it, returning a packet ready - to be used or put on the queue. This assumes a UDP socket - ******************************************************************/ + Read a packet from a socket and parse it, returning a packet ready + to be used or put on the queue. This assumes a UDP socket. +******************************************************************/ + struct packet_struct *read_packet(int fd,enum packet_type packet_type) { struct packet_struct *packet; @@ -709,10 +737,12 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) int length; length = read_udp_socket(fd,buf,sizeof(buf)); - if (length < MIN_DGRAM_SIZE) return(NULL); + if (length < MIN_DGRAM_SIZE) + return(NULL); packet = parse_packet(buf, length, packet_type); - if (!packet) return NULL; + if (!packet) + return NULL; packet->fd = fd; @@ -724,96 +754,99 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) return(packet); } - /******************************************************************* - send a udp packet on a already open socket - ******************************************************************/ + Send a udp packet on a already open socket. +******************************************************************/ + static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) { - BOOL ret = False; - int i; - struct sockaddr_in sock_out; - - /* set the address and port */ - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)&ip); - sock_out.sin_port = htons( port ); - sock_out.sin_family = AF_INET; + BOOL ret = False; + int i; + struct sockaddr_in sock_out; + + /* set the address and port */ + memset((char *)&sock_out,'\0',sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)&ip); + sock_out.sin_port = htons( port ); + sock_out.sin_family = AF_INET; - DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", - len, inet_ntoa(ip), port ) ); + DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", + len, inet_ntoa(ip), port ) ); - /* - * Patch to fix asynch error notifications from Linux kernel. - */ + /* + * Patch to fix asynch error notifications from Linux kernel. + */ - for (i = 0; i < 5; i++) { - ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); - if (ret || errno != ECONNREFUSED) - break; - } + for (i = 0; i < 5; i++) { + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); + if (ret || errno != ECONNREFUSED) + break; + } - if (!ret) - DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", - inet_ntoa(ip),port,strerror(errno))); + if (!ret) + DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", + inet_ntoa(ip),port,strerror(errno))); - if (ret) - num_good_sends++; + if (ret) + num_good_sends++; - return(ret); + return(ret); } /******************************************************************* - build a dgram packet ready for sending + Build a dgram packet ready for sending. - XXXX This currently doesn't handle packets too big for one - datagram. It should split them and use the packet_offset, more and - first flags to handle the fragmentation. Yuck. + XXXX This currently doesn't handle packets too big for one + datagram. It should split them and use the packet_offset, more and + first flags to handle the fragmentation. Yuck. - [...but it isn't clear that we would ever need to send a - a fragmented NBT Datagram. The IP layer does its own - fragmentation to ensure that messages can fit into the path - MTU. It *is* important to be able to receive and rebuild - fragmented NBT datagrams, just in case someone out there - really has implemented this 'feature'. crh -)------ ] + [...but it isn't clear that we would ever need to send a + a fragmented NBT Datagram. The IP layer does its own + fragmentation to ensure that messages can fit into the path + MTU. It *is* important to be able to receive and rebuild + fragmented NBT datagrams, just in case someone out there + really has implemented this 'feature'. crh -)------ ] + +******************************************************************/ - ******************************************************************/ static int build_dgram(char *buf,struct packet_struct *p) { - struct dgram_packet *dgram = &p->packet.dgram; - uchar *ubuf = (uchar *)buf; - int offset=0; - - /* put in the header */ - ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((int)dgram->header.flags.node_type)<<2); - if (dgram->header.flags.more) ubuf[1] |= 1; - if (dgram->header.flags.first) ubuf[1] |= 2; - RSSVAL(ubuf,2,dgram->header.dgm_id); - putip(ubuf+4,(char *)&dgram->header.source_ip); - RSSVAL(ubuf,8,dgram->header.source_port); - RSSVAL(ubuf,12,dgram->header.packet_offset); - - offset = 14; - - if (dgram->header.msg_type == 0x10 || - dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); - offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); - } - - memcpy(ubuf+offset,dgram->data,dgram->datasize); - offset += dgram->datasize; - - /* automatically set the dgm_length - * NOTE: RFC1002 says the dgm_length does *not* - * include the fourteen-byte header. crh - */ - dgram->header.dgm_length = (offset - 14); - RSSVAL(ubuf,10,dgram->header.dgm_length); - - return(offset); + struct dgram_packet *dgram = &p->packet.dgram; + unsigned char *ubuf = (unsigned char *)buf; + int offset=0; + + /* put in the header */ + ubuf[0] = dgram->header.msg_type; + ubuf[1] = (((int)dgram->header.flags.node_type)<<2); + if (dgram->header.flags.more) + ubuf[1] |= 1; + if (dgram->header.flags.first) + ubuf[1] |= 2; + RSSVAL(ubuf,2,dgram->header.dgm_id); + putip(ubuf+4,(char *)&dgram->header.source_ip); + RSSVAL(ubuf,8,dgram->header.source_port); + RSSVAL(ubuf,12,dgram->header.packet_offset); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); + offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); + } + + memcpy(ubuf+offset,dgram->data,dgram->datasize); + offset += dgram->datasize; + + /* automatically set the dgm_length + * NOTE: RFC1002 says the dgm_length does *not* + * include the fourteen-byte header. crh + */ + dgram->header.dgm_length = (offset - 14); + RSSVAL(ubuf,10,dgram->header.dgm_length); + + return(offset); } /******************************************************************* @@ -830,92 +863,99 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) /******************************************************************* Compare two nmb names - ******************************************************************/ +******************************************************************/ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) { - return ((n1->name_type == n2->name_type) && - strequal(n1->name ,n2->name ) && - strequal(n1->scope,n2->scope)); + return ((n1->name_type == n2->name_type) && + strequal(n1->name ,n2->name ) && + strequal(n1->scope,n2->scope)); } /******************************************************************* - build a nmb packet ready for sending + Build a nmb packet ready for sending. + + XXXX this currently relies on not being passed something that expands + to a packet too big for the buffer. Eventually this should be + changed to set the trunc bit so the receiver can request the rest + via tcp (when that becomes supported) +******************************************************************/ - XXXX this currently relies on not being passed something that expands - to a packet too big for the buffer. Eventually this should be - changed to set the trunc bit so the receiver can request the rest - via tcp (when that becomes supported) - ******************************************************************/ static int build_nmb(char *buf,struct packet_struct *p) { - struct nmb_packet *nmb = &p->packet.nmb; - uchar *ubuf = (uchar *)buf; - int offset=0; - - /* put in the header */ - RSSVAL(ubuf,offset,nmb->header.name_trn_id); - ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; - if (nmb->header.response) ubuf[offset+2] |= (1<<7); - if (nmb->header.nm_flags.authoritative && - nmb->header.response) ubuf[offset+2] |= 0x4; - if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; - if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; - if (nmb->header.nm_flags.recursion_available && - nmb->header.response) ubuf[offset+3] |= 0x80; - if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; - ubuf[offset+3] |= (nmb->header.rcode & 0xF); - - RSSVAL(ubuf,offset+4,nmb->header.qdcount); - RSSVAL(ubuf,offset+6,nmb->header.ancount); - RSSVAL(ubuf,offset+8,nmb->header.nscount); - RSSVAL(ubuf,offset+10,nmb->header.arcount); + struct nmb_packet *nmb = &p->packet.nmb; + unsigned char *ubuf = (unsigned char *)buf; + int offset=0; + + /* put in the header */ + RSSVAL(ubuf,offset,nmb->header.name_trn_id); + ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; + if (nmb->header.response) + ubuf[offset+2] |= (1<<7); + if (nmb->header.nm_flags.authoritative && + nmb->header.response) + ubuf[offset+2] |= 0x4; + if (nmb->header.nm_flags.trunc) + ubuf[offset+2] |= 0x2; + if (nmb->header.nm_flags.recursion_desired) + ubuf[offset+2] |= 0x1; + if (nmb->header.nm_flags.recursion_available && + nmb->header.response) + ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.bcast) + ubuf[offset+3] |= 0x10; + ubuf[offset+3] |= (nmb->header.rcode & 0xF); + + RSSVAL(ubuf,offset+4,nmb->header.qdcount); + RSSVAL(ubuf,offset+6,nmb->header.ancount); + RSSVAL(ubuf,offset+8,nmb->header.nscount); + RSSVAL(ubuf,offset+10,nmb->header.arcount); - offset += 12; - if (nmb->header.qdcount) { - /* XXXX this doesn't handle a qdcount of > 1 */ - offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); - RSSVAL(ubuf,offset,nmb->question.question_type); - RSSVAL(ubuf,offset+2,nmb->question.question_class); - offset += 4; - } - - if (nmb->header.ancount) - offset += put_res_rec((char *)ubuf,offset,nmb->answers, - nmb->header.ancount); - - if (nmb->header.nscount) - offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, - nmb->header.nscount); - - /* - * The spec says we must put compressed name pointers - * in the following outgoing packets : - * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, - * NAME_RELEASE_REQUEST. - */ - - if((nmb->header.response == False) && - ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || - (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || - (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && - (nmb->header.arcount == 1)) { - - offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); - - } else if (nmb->header.arcount) { - offset += put_res_rec((char *)ubuf,offset,nmb->additional, - nmb->header.arcount); - } - return(offset); -} + offset += 12; + if (nmb->header.qdcount) { + /* XXXX this doesn't handle a qdcount of > 1 */ + offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); + RSSVAL(ubuf,offset,nmb->question.question_type); + RSSVAL(ubuf,offset+2,nmb->question.question_class); + offset += 4; + } + + if (nmb->header.ancount) + offset += put_res_rec((char *)ubuf,offset,nmb->answers, + nmb->header.ancount); + + if (nmb->header.nscount) + offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, + nmb->header.nscount); + + /* + * The spec says we must put compressed name pointers + * in the following outgoing packets : + * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, + * NAME_RELEASE_REQUEST. + */ + + if((nmb->header.response == False) && + ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || + (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || + (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && + (nmb->header.arcount == 1)) { + + offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); + } else if (nmb->header.arcount) { + offset += put_res_rec((char *)ubuf,offset,nmb->additional, + nmb->header.arcount); + } + return(offset); +} /******************************************************************* -linearise a packet - ******************************************************************/ + Linearise a packet. +******************************************************************/ + int build_packet(char *buf, struct packet_struct *p) { int len = 0; @@ -934,26 +974,29 @@ int build_packet(char *buf, struct packet_struct *p) } /******************************************************************* - send a packet_struct - ******************************************************************/ + Send a packet_struct. +******************************************************************/ + BOOL send_packet(struct packet_struct *p) { - char buf[1024]; - int len=0; + char buf[1024]; + int len=0; - memset(buf,'\0',sizeof(buf)); + memset(buf,'\0',sizeof(buf)); - len = build_packet(buf, p); + len = build_packet(buf, p); - if (!len) return(False); + if (!len) + return(False); - return(send_udp(p->fd,buf,len,p->ip,p->port)); + return(send_udp(p->fd,buf,len,p->ip,p->port)); } /**************************************************************************** - receive a packet with timeout on a open UDP filedescriptor - The timeout is in milliseconds - ***************************************************************************/ + Receive a packet with timeout on a open UDP filedescriptor. + The timeout is in milliseconds +***************************************************************************/ + struct packet_struct *receive_packet(int fd,enum packet_type type,int t) { fd_set fds; @@ -980,12 +1023,12 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) return(NULL); } - /**************************************************************************** - receive a UDP/137 packet either via UDP or from the unexpected packet - queue. The packet must be a reply packet and have the specified trn_id - The timeout is in milliseconds - ***************************************************************************/ + Receive a UDP/137 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified trn_id. + The timeout is in milliseconds. +***************************************************************************/ + struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) { struct packet_struct *p; @@ -993,20 +1036,22 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) p = receive_packet(fd, NMB_PACKET, t); if (p && p->packet.nmb.header.response && - p->packet.nmb.header.name_trn_id == trn_id) { + p->packet.nmb.header.name_trn_id == trn_id) { return p; } - if (p) free_packet(p); + if (p) + free_packet(p); /* try the unexpected packet queue */ return receive_unexpected(NMB_PACKET, trn_id, NULL); } /**************************************************************************** - receive a UDP/138 packet either via UDP or from the unexpected packet - queue. The packet must be a reply packet and have the specified mailslot name - The timeout is in milliseconds - ***************************************************************************/ + Receive a UDP/138 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified mailslot name + The timeout is in milliseconds. +***************************************************************************/ + struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name) { struct packet_struct *p; @@ -1016,16 +1061,17 @@ struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_n if (p && match_mailslot_name(p, mailslot_name)) { return p; } - if (p) free_packet(p); + if (p) + free_packet(p); /* try the unexpected packet queue */ return receive_unexpected(DGRAM_PACKET, 0, mailslot_name); } - /**************************************************************************** - see if a datagram has the right mailslot name + See if a datagram has the right mailslot name. ***************************************************************************/ + BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) { struct dgram_packet *dgram = &p->packet.dgram; @@ -1043,71 +1089,76 @@ BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) return False; } - /**************************************************************************** -return the number of bits that match between two 4 character buffers - ***************************************************************************/ -int matching_quad_bits(uchar *p1, uchar *p2) + Return the number of bits that match between two 4 character buffers +***************************************************************************/ + +int matching_quad_bits(unsigned char *p1, unsigned char *p2) { int i, j, ret = 0; for (i=0; i<4; i++) { - if (p1[i] != p2[i]) break; + if (p1[i] != p2[i]) + break; ret += 8; } - if (i==4) return ret; + if (i==4) + return ret; for (j=0; j<8; j++) { - if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break; + if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) + break; ret++; } return ret; } - -static uchar sort_ip[4]; +static unsigned char sort_ip[4]; /**************************************************************************** -compare two query reply records - ***************************************************************************/ -static int name_query_comp(uchar *p1, uchar *p2) + Compare two query reply records. +***************************************************************************/ + +static int name_query_comp(unsigned char *p1, unsigned char *p2) { return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); } /**************************************************************************** -sort a set of 6 byte name query response records so that the IPs that -have the most leading bits in common with the specified address come first - ***************************************************************************/ + Sort a set of 6 byte name query response records so that the IPs that + have the most leading bits in common with the specified address come first. +***************************************************************************/ + void sort_query_replies(char *data, int n, struct in_addr ip) { - if (n <= 1) return; + if (n <= 1) + return; putip(sort_ip, (char *)&ip); qsort(data, n, 6, QSORT_CAST name_query_comp); } - #define TRUNCATE_NETBIOS_NAME 1 /******************************************************************* - convert, possibly using a stupid microsoft-ism which has destroyed + Convert, possibly using a stupid microsoft-ism which has destroyed the transport independence of netbios (for CIFS vendors that usually use the Win95-type methods, not for NT to NT communication, which uses DCE/RPC and therefore full-length unicode strings...) a dns name into a netbios name. - the netbios name (NOT necessarily null-terminated) is truncated to 15 + The netbios name (NOT necessarily null-terminated) is truncated to 15 characters. ******************************************************************/ -char *dns_to_netbios_name(char *dns_name) + +char *dns_to_netbios_name(const char *dns_name) { - static char netbios_name[16]; + static nstring netbios_name; int i; - StrnCpy(netbios_name, dns_name, 15); + StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1); netbios_name[15] = 0; #ifdef TRUNCATE_NETBIOS_NAME @@ -1116,10 +1167,8 @@ char *dns_to_netbios_name(char *dns_name) netbios name up to and including the '.' this even applies, by mistake, to workgroup (domain) names, which is _really_ daft. */ - for (i = 15; i >= 0; i--) - { - if (netbios_name[i] == '.') - { + for (i = 0; i >= 15; i--) { + if (netbios_name[i] == '.') { netbios_name[i] = 0; break; } @@ -1129,146 +1178,146 @@ char *dns_to_netbios_name(char *dns_name) return netbios_name; } - /**************************************************************************** -interpret the weird netbios "name" into a unix fstring. Return the name type + Interpret the weird netbios "name" into a unix fstring. Return the name type. ****************************************************************************/ + static int name_interpret(char *in, fstring name) { - int ret; - int len = (*in++) / 2; - fstring out_string; - char *out = out_string; - - *out=0; - - if (len > 30 || len<1) return(0); - - while (len--) - { - if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { - *out = 0; - return(0); - } - *out = ((in[0]-'A')<<4) + (in[1]-'A'); - in += 2; - out++; - } - ret = out[-1]; - out[-1] = 0; + int ret; + int len = (*in++) / 2; + fstring out_string; + char *out = out_string; + + *out=0; + + if (len > 30 || len<1) + return(0); + + while (len--) { + if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { + *out = 0; + return(0); + } + *out = ((in[0]-'A')<<4) + (in[1]-'A'); + in += 2; + out++; + } + ret = out[-1]; + out[-1] = 0; #ifdef NETBIOS_SCOPE - /* Handle any scope names */ - while(*in) - { - *out++ = '.'; /* Scope names are separated by periods */ - len = *(uchar *)in++; - StrnCpy(out, in, len); - out += len; - *out=0; - in += len; - } + /* Handle any scope names */ + while(*in) { + *out++ = '.'; /* Scope names are separated by periods */ + len = *(unsigned char *)in++; + StrnCpy(out, in, len); + out += len; + *out=0; + in += len; + } #endif - pull_ascii(name, out_string, sizeof(fstring), sizeof(out_string), STR_TERMINATE); + pull_ascii_fstring(name, out_string); - return(ret); + return(ret); } /**************************************************************************** -mangle a name into netbios format - - Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. + Mangle a name into netbios format. + Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. ****************************************************************************/ + int name_mangle( char *In, char *Out, char name_type ) - { - int i; - int c; - int len; - char buf[20]; - char *p = Out; - - /* Safely copy the input string, In, into buf[]. */ - (void)memset( buf, 0, 20 ); - if (strcmp(In,"*") == 0) - buf[0] = '*'; - else - (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); - - /* Place the length of the first field into the output buffer. */ - p[0] = 32; - p++; - - /* Now convert the name to the rfc1001/1002 format. */ - for( i = 0; i < 16; i++ ) - { - c = toupper( buf[i] ); - p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; - p[(i*2)+1] = (c & 0x000F) + 'A'; - } - p += 32; - p[0] = '\0'; - - /* Add the scope string. */ - for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) - { - switch( (global_scope())[i] ) - { - case '\0': - p[0] = len; - if( len > 0 ) - p[len+1] = 0; - return( name_len(Out) ); - case '.': - p[0] = len; - p += (len + 1); - len = -1; - break; - default: - p[len+1] = (global_scope())[i]; - break; - } - } - - return( name_len(Out) ); - } /* name_mangle */ +{ + int i; + int c; + int len; + char buf[20]; + char *p = Out; + + /* Safely copy the input string, In, into buf[]. */ + memset( buf, 0, 20 ); + if (strcmp(In,"*") == 0) { + buf[0] = '*'; + } else { + slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); + } + /* Place the length of the first field into the output buffer. */ + p[0] = 32; + p++; + + /* Now convert the name to the rfc1001/1002 format. */ + for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) { + c = toupper( buf[i] ); + p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; + p[(i*2)+1] = (c & 0x000F) + 'A'; + } + p += 32; + p[0] = '\0'; + + /* Add the scope string. */ + for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) { + switch( (global_scope())[i] ) { + case '\0': + p[0] = len; + if( len > 0 ) + p[len+1] = 0; + return( name_len(Out) ); + case '.': + p[0] = len; + p += (len + 1); + len = -1; + break; + default: + p[len+1] = (global_scope())[i]; + break; + } + } + + return( name_len(Out) ); +} /**************************************************************************** -find a pointer to a netbios name + Find a pointer to a netbios name. ****************************************************************************/ + static char *name_ptr(char *buf,int ofs) { - uchar c = *(uchar *)(buf+ofs); - - if ((c & 0xC0) == 0xC0) - { - uint16 l = RSVAL(buf, ofs) & 0x3FFF; - DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); - return(buf + l); - } - else - return(buf+ofs); + unsigned char c = *(unsigned char *)(buf+ofs); + + if ((c & 0xC0) == 0xC0) { + uint16 l = RSVAL(buf, ofs) & 0x3FFF; + DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); + return(buf + l); + } else { + return(buf+ofs); + } } /**************************************************************************** -extract a netbios name from a buf (into a unix string) return name type + Extract a netbios name from a buf (into a unix string) return name type. ****************************************************************************/ + int name_extract(char *buf,int ofs, fstring name) { - char *p = name_ptr(buf,ofs); - int d = PTR_DIFF(p,buf+ofs); - pstrcpy(name,""); - if (d < -50 || d > 50) return(0); - return(name_interpret(p,name)); + char *p = name_ptr(buf,ofs); + int d = PTR_DIFF(p,buf+ofs); + + name[0] = '\0'; + if (d < -50 || d > 50) + return(0); + return(name_interpret(p,name)); } /**************************************************************************** -return the total storage length of a mangled name + Return the total storage length of a mangled name. ****************************************************************************/ + int name_len(char *s1) { /* NOTE: this argument _must_ be unsigned */ - uchar *s = (uchar *)s1; + unsigned char *s = (unsigned char *)s1; int len; /* If the two high bits of the byte are set, return 2. */ @@ -1282,4 +1331,4 @@ int name_len(char *s1) } return(len); -} /* name_len */ +} diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index aeac9e4c84..bca7a75fbb 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -171,7 +171,7 @@ int reply_special(char *inbuf,char *outbuf) int outsize = 4; int msg_type = CVAL(inbuf,0); int msg_flags = CVAL(inbuf,1); - pstring name1,name2; + fstring name1,name2; char name_type = 0; static BOOL already_got_session = False; -- cgit From 9a699d74efbcbbb8607c7dea2734d7acb3478896 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Mar 2004 02:16:26 +0000 Subject: Modified fix for bugid #784. Based on a patch from moriyama@miraclelinux.com (MORIYAMA Masayuki). Don't use nstrings to hold workgroup and netbios names. The problem with them is that MB netbios and workgroup names in unix charset (particularly utf8) may be up to 3x bigger than the name when represented in dos charset (ie. cp932). So go back to using fstrings for these but translate into nstrings (ie. 16 byte length values) for transport on the wire. Jeremy. (This used to be commit 128dec9ae68fd357550de2649d54056ca4fc65cf) --- source3/include/nameserv.h | 8 ++-- source3/lib/charcnv.c | 9 +++-- source3/lib/util_str.c | 1 - source3/libsmb/libsmbclient.c | 2 +- source3/libsmb/namequery.c | 4 +- source3/libsmb/nmblib.c | 28 +++++++------ source3/nmbd/asyncdns.c | 4 +- source3/nmbd/nmbd_become_dmb.c | 16 ++++---- source3/nmbd/nmbd_become_lmb.c | 22 +++++------ source3/nmbd/nmbd_browserdb.c | 4 +- source3/nmbd/nmbd_browsesync.c | 22 +++++------ source3/nmbd/nmbd_elections.c | 16 ++++---- source3/nmbd/nmbd_incomingdgrams.c | 76 ++++++++++++++++++------------------ source3/nmbd/nmbd_incomingrequests.c | 31 ++++++++------- source3/nmbd/nmbd_logonnames.c | 8 ++-- source3/nmbd/nmbd_mynames.c | 4 +- source3/nmbd/nmbd_namelistdb.c | 8 ++-- source3/nmbd/nmbd_nameregister.c | 23 +++++------ source3/nmbd/nmbd_packets.c | 8 ++-- source3/nmbd/nmbd_processlogon.c | 6 +-- source3/nmbd/nmbd_synclists.c | 10 ++--- source3/nmbd/nmbd_winsproxy.c | 8 ++-- source3/nmbd/nmbd_winsserver.c | 22 +++++------ source3/nmbd/nmbd_workgroupdb.c | 23 ++++++----- source3/smbd/negprot.c | 10 +++-- 25 files changed, 197 insertions(+), 176 deletions(-) diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h index 1e867d620b..5362960d62 100644 --- a/source3/include/nameserv.h +++ b/source3/include/nameserv.h @@ -226,8 +226,8 @@ struct name_record { /* Browser cache for synchronising browse lists. */ struct browse_cache_record { ubi_dlNode node[1]; - nstring lmb_name; - nstring work_group; + fstring lmb_name; + fstring work_group; struct in_addr ip; time_t sync_time; time_t death_time; /* The time the record must be removed. */ @@ -265,9 +265,9 @@ struct work_record { enum logon_state log_state; /* Work group info. */ - nstring work_group; + fstring work_group; int token; /* Used when communicating with backup browsers. */ - nstring local_master_browser_name; /* Current local master browser. */ + fstring local_master_browser_name; /* Current local master browser. */ /* Announce info. */ time_t lastannounce_time; diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 7227a946bc..d38bfdb534 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -839,7 +839,7 @@ size_t push_ascii_nstring(void *dest, const char *src) } dest_len = 0; - for (i = 0; i < buffer_len; i++) { + for (i = 0; buffer[i] != 0 && (i < buffer_len); i++) { unsigned char mb[10]; /* Convert one smb_ucs2_t character at a time. */ size_t mb_len = convert_string(CH_UCS2, CH_DOS, buffer+i, sizeof(smb_ucs2_t), mb, sizeof(mb), False); @@ -847,6 +847,7 @@ size_t push_ascii_nstring(void *dest, const char *src) memcpy((char *)dest + dest_len, mb, mb_len); dest_len += mb_len; } else { + errno = E2BIG; break; } } @@ -912,9 +913,11 @@ size_t pull_ascii_fstring(char *dest, const void *src) return pull_ascii(dest, src, sizeof(fstring), -1, STR_TERMINATE); } -size_t pull_ascii_nstring(char *dest, const void *src) +/* When pulling an nstring it can expand into a larger size (dos cp -> utf8). Cope with this. */ + +size_t pull_ascii_nstring(char *dest, size_t dest_len, const void *src) { - return pull_ascii(dest, src, sizeof(nstring), sizeof(nstring), STR_TERMINATE); + return pull_ascii(dest, src, dest_len, sizeof(nstring), STR_TERMINATE); } /** diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index b8cf052862..2be8b7eb64 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1307,7 +1307,6 @@ char *strstr_m(const char *src, const char *findstr) char *retp; size_t findstr_len = 0; - size_t find_w_len; /* for correctness */ if (!findstr[0]) { diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 37e794478d..35e8a9786b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1787,7 +1787,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!is_ipaddress(server) && /* Not an IP addr so check next */ (resolve_name(server, &rem_ip, 0x1d) || /* Found LMB */ resolve_name(server, &rem_ip, 0x1b) )) { /* Found DMB */ - pstring buserver; + fstring buserver; dir->dir_type = SMBC_SERVER; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index b6d1f8bda2..b9bc4e1166 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -163,7 +163,7 @@ struct node_status *node_status_query(int fd,struct nmb_name *name, a servers name given its IP. Return the matched name in *name. **************************************************************************/ -BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name) +BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name) { struct node_status *status = NULL; struct nmb_name nname; @@ -202,7 +202,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t if (i == count) goto done; - pull_ascii_nstring(name, status[i].name); + pull_ascii_nstring(name, sizeof(fstring), status[i].name); /* Store the result in the cache. */ /* but don't store an entry for 0x1c names here. Here we have diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index cbe495cd95..bc2cca0e0e 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -285,7 +285,7 @@ static void put_name(char *dest, const char *name, int pad, unsigned int name_ty static int put_nmb_name(char *buf,int offset,struct nmb_name *name) { int ret,m; - fstring buf1; + nstring buf1; char *p; if (strcmp(name->name,"*") == 0) { @@ -1230,17 +1230,24 @@ static int name_interpret(char *in, fstring name) int name_mangle( char *In, char *Out, char name_type ) { int i; - int c; int len; - char buf[20]; + nstring buf; char *p = Out; /* Safely copy the input string, In, into buf[]. */ - memset( buf, 0, 20 ); - if (strcmp(In,"*") == 0) { - buf[0] = '*'; - } else { - slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); + if (strcmp(In,"*") == 0) + put_name(buf, "*", '\0', 0x00); + else { + /* We use an fstring here as mb dos names can expend x3 when + going to utf8. */ + fstring buf_unix; + nstring buf_dos; + + pull_ascii_fstring(buf_unix, In); + strupper_m(buf_unix); + + push_ascii_nstring(buf_dos, buf_unix); + put_name(buf, buf_dos, ' ', name_type); } /* Place the length of the first field into the output buffer. */ @@ -1249,9 +1256,8 @@ int name_mangle( char *In, char *Out, char name_type ) /* Now convert the name to the rfc1001/1002 format. */ for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) { - c = toupper( buf[i] ); - p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; - p[(i*2)+1] = (c & 0x000F) + 'A'; + p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A'; + p[(i*2)+1] = (buf[i] & 0x000F) + 'A'; } p += 32; p[0] = '\0'; diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c index 6d5d487b11..dafbff7af2 100644 --- a/source3/nmbd/asyncdns.c +++ b/source3/nmbd/asyncdns.c @@ -27,9 +27,9 @@ static struct name_record *add_dns_result(struct nmb_name *question, struct in_addr addr) { int name_type = question->name_type; - nstring qname; + fstring qname; - pull_ascii_nstring(qname, question->name); + pull_ascii_nstring(qname, sizeof(qname), question->name); if (!addr.s_addr) { /* add the fail to WINS cache of names. give it 1 hour in the cache */ diff --git a/source3/nmbd/nmbd_become_dmb.c b/source3/nmbd/nmbd_become_dmb.c index 46d37fbb81..c9b0a22580 100644 --- a/source3/nmbd/nmbd_become_dmb.c +++ b/source3/nmbd/nmbd_become_dmb.c @@ -37,11 +37,11 @@ static void become_domain_master_fail(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *fail_name) { - nstring failname; + fstring failname; struct work_record *work; struct server_record *servrec; - pull_ascii_nstring(failname, fail_name->name); + pull_ascii_nstring(failname, sizeof(failname), fail_name->name); work = find_workgroup_on_subnet(subrec, failname); if(!work) { DEBUG(0,("become_domain_master_fail: Error - cannot find \ @@ -80,11 +80,11 @@ static void become_domain_master_stage2(struct subnet_record *subrec, uint16 nb_flags, int ttl, struct in_addr registered_ip) { - nstring regname; + fstring regname; struct work_record *work; struct server_record *servrec; - pull_ascii_nstring(regname, registered_name->name); + pull_ascii_nstring(regname, sizeof(regname), registered_name->name); work = find_workgroup_on_subnet( subrec, regname); if(!work) { @@ -200,8 +200,8 @@ static void become_domain_master_query_success(struct subnet_record *subrec, struct nmb_name *nmbname, struct in_addr ip, struct res_rec *rrec) { - nstring name; - pull_ascii_nstring(name, nmbname->name); + fstring name; + pull_ascii_nstring(name, sizeof(name), nmbname->name); /* If the given ip is not ours, then we can't become a domain controler as the name is already registered. @@ -241,7 +241,7 @@ static void become_domain_master_query_fail(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *question_name, int fail_code) { - nstring name; + fstring name; /* If the query was unicast, and the error is not NAM_ERR (name didn't exist), then this is a failure. Otherwise, not finding the name is what we want. */ @@ -254,7 +254,7 @@ querying WINS server for name %s.\n", } /* Otherwise - not having the name allows us to register it. */ - pull_ascii_nstring(name, question_name->name); + pull_ascii_nstring(name, sizeof(name), question_name->name); become_domain_master_stage1(subrec, name); } diff --git a/source3/nmbd/nmbd_become_lmb.c b/source3/nmbd/nmbd_become_lmb.c index 2370c7ba36..8d66320f3e 100644 --- a/source3/nmbd/nmbd_become_lmb.c +++ b/source3/nmbd/nmbd_become_lmb.c @@ -33,11 +33,11 @@ extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */ void insert_permanent_name_into_unicast( struct subnet_record *subrec, struct nmb_name *nmbname, uint16 nb_type ) { - nstring name; + fstring name; struct name_record *namerec; if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL) { - pull_ascii_nstring(name, nmbname->name); + pull_ascii_nstring(name, sizeof(name), nmbname->name); /* The name needs to be created on the unicast subnet. */ (void)add_name_to_subnet( unicast_subnet, name, nmbname->name_type, nb_type, @@ -135,7 +135,7 @@ static void unbecome_local_master_success(struct subnet_record *subrec, struct in_addr released_ip) { BOOL force_new_election = False; - nstring relname; + fstring relname; memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL)); @@ -143,7 +143,7 @@ static void unbecome_local_master_success(struct subnet_record *subrec, nmb_namestr(released_name))); /* Now reset the workgroup and server state. */ - pull_ascii_nstring(relname, released_name->name); + pull_ascii_nstring(relname, sizeof(relname), released_name->name); reset_workgroup_state( subrec, relname, force_new_election ); if( DEBUGLVL( 0 ) ) { @@ -166,7 +166,7 @@ static void unbecome_local_master_fail(struct subnet_record *subrec, struct resp struct name_record *namerec; struct userdata_struct *userdata = rrec->userdata; BOOL force_new_election = False; - nstring failname; + fstring failname; memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL)); @@ -179,7 +179,7 @@ Removing from namelist anyway.\n", nmb_namestr(fail_name))); remove_name_from_namelist(subrec, namerec); /* Now reset the workgroup and server state. */ - pull_ascii_nstring(failname, fail_name->name); + pull_ascii_nstring(failname, sizeof(failname), fail_name->name); reset_workgroup_state( subrec, failname, force_new_election ); if( DEBUGLVL( 0 ) ) { @@ -330,9 +330,9 @@ static void become_local_master_stage2(struct subnet_record *subrec, struct server_record *sl; struct work_record *work; struct server_record *servrec; - nstring regname; + fstring regname; - pull_ascii_nstring(regname, registered_name->name); + pull_ascii_nstring(regname, sizeof(regname), registered_name->name); work = find_workgroup_on_subnet( subrec, regname); if(!work) { @@ -410,13 +410,13 @@ static void become_local_master_fail2(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *fail_name) { - nstring failname; + fstring failname; struct work_record *work; DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \ Failed to become a local master browser.\n", nmb_namestr(fail_name), subrec->subnet_name)); - pull_ascii_nstring(failname, fail_name->name); + pull_ascii_nstring(failname, sizeof(failname), fail_name->name); work = find_workgroup_on_subnet( subrec, failname); if(!work) { @@ -590,5 +590,5 @@ local_master_browser_name for workgroup %s to workgroup name.\n", } #endif - nstrcpy(work->local_master_browser_name, newname); + fstrcpy(work->local_master_browser_name, newname); } diff --git a/source3/nmbd/nmbd_browserdb.c b/source3/nmbd/nmbd_browserdb.c index 443edf599d..d781259156 100644 --- a/source3/nmbd/nmbd_browserdb.c +++ b/source3/nmbd/nmbd_browserdb.c @@ -106,8 +106,8 @@ struct browse_cache_record *create_browser_in_lmb_cache( const char *work_name, /* Allow the new lmb to miss an announce period before we remove it. */ browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 ); - nstrcpy( browc->lmb_name, browser_name); - nstrcpy( browc->work_group, work_name); + fstrcpy( browc->lmb_name, browser_name); + fstrcpy( browc->work_group, work_name); strupper_m( browc->lmb_name ); strupper_m( browc->work_group ); diff --git a/source3/nmbd/nmbd_browsesync.c b/source3/nmbd/nmbd_browsesync.c index 6cde88651f..454c349767 100644 --- a/source3/nmbd/nmbd_browsesync.c +++ b/source3/nmbd/nmbd_browsesync.c @@ -146,7 +146,7 @@ As a local master browser, do a sync with a domain master browser. static void sync_with_dmb(struct work_record *work) { - nstring dmb_name; + fstring dmb_name; if( DEBUGLVL( 2 ) ) { dbgtext( "sync_with_dmb:\n" ); @@ -156,7 +156,7 @@ static void sync_with_dmb(struct work_record *work) dbgtext( "for workgroup %s\n", work->work_group ); } - pull_ascii_nstring(dmb_name, work->dmb_name.name); + pull_ascii_nstring(dmb_name, sizeof(fstring), work->dmb_name.name); sync_browse_lists(work, dmb_name, work->dmb_name.name_type, work->dmb_addr, False, True); } @@ -197,11 +197,11 @@ static void domain_master_node_status_success(struct subnet_record *subrec, p += 1; while (numnames--) { - nstring qname; + fstring qname; uint16 nb_flags; int name_type; - pull_ascii_nstring(qname, p); + pull_ascii_nstring(qname, sizeof(qname), p); name_type = CVAL(p,15); nb_flags = get_nb_flags(&p[16]); trim_char(qname,'\0',' '); @@ -278,9 +278,9 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec, struct nmb_name nmbname; struct userdata_struct *userdata; size_t size = sizeof(struct userdata_struct) + sizeof(fstring)+1; - nstring qname; + fstring qname; - pull_ascii_nstring(qname, q_name->name); + pull_ascii_nstring(qname, sizeof(qname), q_name->name); if( !(work = find_workgroup_on_subnet(subrec, qname)) ) { if( DEBUGLVL( 0 ) ) { dbgtext( "find_domain_master_name_query_success:\n" ); @@ -420,11 +420,11 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub p += 1; while (numnames--) { - nstring qname; + fstring qname; uint16 nb_flags; int name_type; - pull_ascii_nstring(qname, p); + pull_ascii_nstring(qname, sizeof(qname), p); name_type = CVAL(p,15); nb_flags = get_nb_flags(&p[16]); trim_char(qname,'\0',' '); @@ -460,7 +460,7 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub return; /* remember who the master is */ - nstrcpy(work->local_master_browser_name, server_name); + fstrcpy(work->local_master_browser_name, server_name); make_nmb_name(&nmbname, server_name, 0x20); work->dmb_name = nmbname; work->dmb_addr = from_ip; @@ -647,7 +647,7 @@ void sync_all_dmbs(time_t t) /* sync with a probability of 1/count */ for (work=unicast_subnet->workgrouplist; work; work = work->next) { if (strncmp(lp_workgroup(), work->work_group, sizeof(nstring))) { - nstring dmb_name; + fstring dmb_name; if (((unsigned)sys_random()) % count != 0) continue; @@ -662,7 +662,7 @@ void sync_all_dmbs(time_t t) 0x20); } - pull_ascii_nstring(dmb_name, work->dmb_name.name); + pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name); DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n", dmb_name, inet_ntoa(work->dmb_addr))); diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c index 19b00f1f4d..882c26ce80 100644 --- a/source3/nmbd/nmbd_elections.c +++ b/source3/nmbd/nmbd_elections.c @@ -70,8 +70,8 @@ static void check_for_master_browser_success(struct subnet_record *subrec, struct nmb_name *answer_name, struct in_addr answer_ip, struct res_rec *rrec) { - nstring aname; - pull_ascii_nstring(aname, answer_name->name); + fstring aname; + pull_ascii_nstring(aname, sizeof(aname), answer_name->name); DEBUG(3,("check_for_master_browser_success: Local master browser for workgroup %s exists at \ IP %s (just checking).\n", aname, inet_ntoa(answer_ip) )); } @@ -85,10 +85,10 @@ static void check_for_master_browser_fail( struct subnet_record *subrec, struct nmb_name *question_name, int fail_code) { - nstring workgroup_name; + fstring workgroup_name; struct work_record *work; - pull_ascii_nstring(workgroup_name,question_name->name); + pull_ascii_nstring(workgroup_name,sizeof(workgroup_name),question_name->name); work = find_workgroup_on_subnet(subrec, workgroup_name); if(work == NULL) { @@ -263,12 +263,12 @@ void process_election(struct subnet_record *subrec, struct packet_struct *p, cha int version = CVAL(buf,0); uint32 criterion = IVAL(buf,1); int timeup = IVAL(buf,5)/1000; - nstring server_name; + fstring server_name; struct work_record *work; - nstring workgroup_name; + fstring workgroup_name; - pull_ascii_nstring(server_name, buf+13); - pull_ascii_nstring(workgroup_name, dgram->dest_name.name); + pull_ascii_nstring(server_name, sizeof(server_name), buf+13); + pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name); START_PROFILE(election); server_name[15] = 0; diff --git a/source3/nmbd/nmbd_incomingdgrams.c b/source3/nmbd/nmbd_incomingdgrams.c index f646e39716..1450610e19 100644 --- a/source3/nmbd/nmbd_incomingdgrams.c +++ b/source3/nmbd/nmbd_incomingdgrams.c @@ -97,21 +97,21 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p { struct dgram_packet *dgram = &p->packet.dgram; int ttl = IVAL(buf,1)/1000; - nstring announce_name; + fstring announce_name; uint32 servertype = IVAL(buf,23); fstring comment; struct work_record *work; struct server_record *servrec; - nstring work_name; - nstring source_name; + fstring work_name; + fstring source_name; START_PROFILE(host_announce); pull_ascii_fstring(comment, buf+31); comment[42] = 0; - pull_ascii_nstring(announce_name, buf+5); - pull_ascii_nstring(source_name, dgram->source_name.name); + pull_ascii_nstring(announce_name, sizeof(announce_name), buf+5); + pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); DEBUG(3,("process_host_announce: from %s<%02x> IP %s to \ %s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip), @@ -133,7 +133,7 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p } /* For a host announce the workgroup name is the destination name. */ - pull_ascii_nstring(work_name, dgram->dest_name.name); + pull_ascii_nstring(work_name, sizeof(work_name), dgram->dest_name.name); /* * Syntax servers version 5.1 send HostAnnounce packets to @@ -144,7 +144,7 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p */ if(strequal(work_name, global_myname())) - nstrcpy(work_name,lp_workgroup()); + fstrcpy(work_name,lp_workgroup()); /* * We are being very agressive here in adding a workgroup @@ -198,19 +198,19 @@ void process_workgroup_announce(struct subnet_record *subrec, struct packet_stru { struct dgram_packet *dgram = &p->packet.dgram; int ttl = IVAL(buf,1)/1000; - nstring workgroup_announce_name; - nstring master_name; + fstring workgroup_announce_name; + fstring master_name; uint32 servertype = IVAL(buf,23); struct work_record *work; - nstring source_name; - nstring dest_name; + fstring source_name; + fstring dest_name; START_PROFILE(workgroup_announce); - pull_ascii_nstring(workgroup_announce_name,buf+5); - pull_ascii_nstring(master_name,buf+31); - pull_ascii_nstring(source_name,dgram->source_name.name); - pull_ascii_nstring(dest_name,dgram->dest_name.name); + pull_ascii_nstring(workgroup_announce_name,sizeof(workgroup_announce_name),buf+5); + pull_ascii_nstring(master_name,sizeof(master_name),buf+31); + pull_ascii_nstring(source_name,sizeof(source_name),dgram->source_name.name); + pull_ascii_nstring(dest_name,sizeof(dest_name),dgram->dest_name.name); DEBUG(3,("process_workgroup_announce: from %s<%02x> IP %s to \ %s for workgroup %s.\n", source_name, source_name[15], inet_ntoa(p->ip), @@ -255,21 +255,21 @@ void process_local_master_announce(struct subnet_record *subrec, struct packet_s { struct dgram_packet *dgram = &p->packet.dgram; int ttl = IVAL(buf,1)/1000; - nstring server_name; + fstring server_name; uint32 servertype = IVAL(buf,23); fstring comment; - nstring work_name; + fstring work_name; struct work_record *work; struct server_record *servrec; - nstring source_name; + fstring source_name; START_PROFILE(local_master_announce); - pull_ascii_nstring(server_name,buf+5); + pull_ascii_nstring(server_name,sizeof(server_name),buf+5); pull_ascii_fstring(comment, buf+31); comment[42] = 0; - pull_ascii_nstring(source_name, dgram->source_name.name); - pull_ascii_nstring(work_name, dgram->dest_name.name); + pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); + pull_ascii_nstring(work_name, sizeof(work_name), dgram->dest_name.name); DEBUG(3,("process_local_master_announce: from %s<%02x> IP %s to \ %s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip), @@ -369,13 +369,13 @@ done: void process_master_browser_announce(struct subnet_record *subrec, struct packet_struct *p,char *buf) { - nstring local_master_name; + fstring local_master_name; struct work_record *work; struct browse_cache_record *browrec; START_PROFILE(master_browser_announce); - pull_ascii_nstring(local_master_name,buf); + pull_ascii_nstring(local_master_name,sizeof(local_master_name),buf); DEBUG(3,("process_master_browser_announce: Local master announce from %s IP %s.\n", local_master_name, inet_ntoa(p->ip))); @@ -425,11 +425,11 @@ void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct int osmajor=CVAL(buf,5); /* major version of node software */ int osminor=CVAL(buf,6); /* minor version of node software */ int ttl = SVAL(buf,7); - nstring announce_name; + fstring announce_name; struct work_record *work; struct server_record *servrec; - nstring work_name; - nstring source_name; + fstring work_name; + fstring source_name; fstring comment; char *s = buf+9; @@ -437,10 +437,10 @@ void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct s = skip_string(s,1); pull_ascii(comment, s, sizeof(fstring), 43, STR_TERMINATE); - pull_ascii_nstring(announce_name,buf+9); - pull_ascii_nstring(source_name,dgram->source_name.name); + pull_ascii_nstring(announce_name,sizeof(announce_name),buf+9); + pull_ascii_nstring(source_name,sizeof(source_name),dgram->source_name.name); /* For a LanMan host announce the workgroup name is the destination name. */ - pull_ascii_nstring(work_name,dgram->dest_name.name); + pull_ascii_nstring(work_name,sizeof(work_name),dgram->dest_name.name); DEBUG(3,("process_lm_host_announce: LM Announcement from %s IP %s to \ %s for server %s.\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), @@ -479,7 +479,7 @@ originate from OS/2 Warp client. Ignoring packet.\n")); */ if(strequal(work_name, global_myname())) - nstrcpy(work_name,lp_workgroup()); + fstrcpy(work_name,lp_workgroup()); /* * We are being very agressive here in adding a workgroup @@ -541,7 +541,7 @@ static void send_backup_list_response(struct subnet_record *subrec, char outbuf[1024]; char *p, *countptr; unsigned int count = 0; - nstring send_to_namestr; + fstring send_to_namestr; #if 0 struct server_record *servrec; #endif @@ -612,7 +612,7 @@ static void send_backup_list_response(struct subnet_record *subrec, SCVAL(countptr, 0, count); - pull_ascii_nstring(send_to_namestr, send_to_name->name); + pull_ascii_nstring(send_to_namestr, sizeof(send_to_namestr), send_to_name->name); DEBUG(4,("send_backup_list_response: sending response to %s<00> IP %s with %d servers.\n", send_to_namestr, inet_ntoa(sendto_ip), count)); @@ -642,11 +642,11 @@ void process_get_backup_list_request(struct subnet_record *subrec, unsigned char max_number_requested = CVAL(buf,0); uint32 token = IVAL(buf,1); /* Sender's key index for the workgroup. */ int name_type = dgram->dest_name.name_type; - nstring workgroup_name; + fstring workgroup_name; struct subnet_record *search_subrec = subrec; START_PROFILE(get_backup_list); - pull_ascii_nstring(workgroup_name, dgram->dest_name.name); + pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name); DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), @@ -774,11 +774,11 @@ void process_announce_request(struct subnet_record *subrec, struct packet_struct { struct dgram_packet *dgram = &p->packet.dgram; struct work_record *work; - nstring workgroup_name; + fstring workgroup_name; START_PROFILE(announce_request); - pull_ascii_nstring(workgroup_name, dgram->dest_name.name); + pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name); DEBUG(3,("process_announce_request: Announce request from %s IP %s to %s.\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name))); @@ -814,11 +814,11 @@ done: void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf) { struct dgram_packet *dgram = &p->packet.dgram; - nstring workgroup_name; + fstring workgroup_name; START_PROFILE(lm_announce_request); - pull_ascii_nstring(workgroup_name, dgram->dest_name.name); + pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name); DEBUG(3,("process_lm_announce_request: Announce request from %s IP %s to %s.\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name))); diff --git a/source3/nmbd/nmbd_incomingrequests.c b/source3/nmbd/nmbd_incomingrequests.c index dd999fbdf7..d43cefc0df 100644 --- a/source3/nmbd/nmbd_incomingrequests.c +++ b/source3/nmbd/nmbd_incomingrequests.c @@ -58,7 +58,7 @@ void process_name_release_request(struct subnet_record *subrec, struct nmb_packet *nmb = &p->packet.nmb; struct in_addr owner_ip; struct nmb_name *question = &nmb->question.question_name; - nstring qname; + fstring qname; BOOL bcast = nmb->header.nm_flags.bcast; uint16 nb_flags = get_nb_flags(nmb->additional->rdata); BOOL group = (nb_flags & NB_GROUP) ? True : False; @@ -98,7 +98,7 @@ subnet %s from owner IP %s\n", * names and *don't set the group bit* !!!!! */ - pull_ascii_nstring(qname, question->name); + pull_ascii_nstring(qname, sizeof(qname), question->name); if( !group && !ismyip(owner_ip) && strequal(qname, lp_workgroup()) && ((question->name_type == 0x0) || (question->name_type == 0x1e))) { DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \ @@ -275,11 +275,13 @@ We put our own names first, then in alphabetical order. static int status_compare(char *n1,char *n2) { - nstring name1, name2; + fstring name1, name2; int l1,l2,l3; - pull_ascii_nstring(name1, n1); - pull_ascii_nstring(name2, n2); + memset(name1, '\0', sizeof(name1)); + memset(name2, '\0', sizeof(name2)); + pull_ascii_nstring(name1, sizeof(name1), n1); + pull_ascii_nstring(name2, sizeof(name2), n2); n1 = name1; n2 = name2; @@ -298,7 +300,7 @@ static int status_compare(char *n1,char *n2) (l1!=l3 || strncmp(n1,global_myname(),l3) != 0)) return 1; - return memcmp(n1,n2,sizeof(nstring)); + return memcmp(n1,n2,sizeof(fstring)); } /**************************************************************************** @@ -308,14 +310,14 @@ static int status_compare(char *n1,char *n2) void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - nstring qname; + fstring qname; int ques_type = nmb->question.question_name.name_type; char rdata[MAX_DGRAM_SIZE]; char *countptr, *buf, *bufend, *buf0; int names_added,i; struct name_record *namerec; - pull_ascii_nstring(qname, nmb->question.question_name.name); + pull_ascii_nstring(qname, sizeof(qname), nmb->question.question_name.name); DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \ subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip), subrec->subnet_name)); @@ -342,9 +344,9 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name), while (buf < bufend) { if( (namerec->data.source == SELF_NAME) || (namerec->data.source == PERMANENT_NAME) ) { int name_type = namerec->name.name_type; - nstring name; + fstring name; - pull_ascii_nstring(name, namerec->name.name); + pull_ascii_nstring(name, sizeof(name), namerec->name.name); strupper_m(name); if (!strequal(name,"*") && !strequal(name,"__SAMBA__") && @@ -352,10 +354,11 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name), ques_type < 0x1b || ques_type >= 0x20 || strequal(qname, name))) { /* Start with the name. */ - nstring tmp_name; - memset(tmp_name,'\0',sizeof(tmp_name)); - snprintf(tmp_name, sizeof(tmp_name), "%-15.15s",name); - push_ascii_nstring(buf, tmp_name); + size_t len; + push_ascii_nstring(buf, name); + len = strlen(buf); + memset(buf + len, ' ', MAX_NETBIOSNAME_LEN - len - 1); + buf[MAX_NETBIOSNAME_LEN - 1] = '\0'; /* Put the name type and netbios flags in the buffer. */ diff --git a/source3/nmbd/nmbd_logonnames.c b/source3/nmbd/nmbd_logonnames.c index f79fc56f7b..b6e841139f 100644 --- a/source3/nmbd/nmbd_logonnames.c +++ b/source3/nmbd/nmbd_logonnames.c @@ -35,11 +35,11 @@ static void become_logon_server_fail(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *fail_name) { - nstring failname; + fstring failname; struct work_record *work; struct server_record *servrec; - pull_ascii_nstring(failname, fail_name->name); + pull_ascii_nstring(failname, sizeof(failname), fail_name->name); work = find_workgroup_on_subnet(subrec, failname); if(!work) { DEBUG(0,("become_logon_server_fail: Error - cannot find \ @@ -76,11 +76,11 @@ static void become_logon_server_success(struct subnet_record *subrec, uint16 nb_flags, int ttl, struct in_addr registered_ip) { - nstring reg_name; + fstring reg_name; struct work_record *work; struct server_record *servrec; - pull_ascii_nstring(reg_name, registered_name->name); + pull_ascii_nstring(reg_name, sizeof(reg_name), registered_name->name); work = find_workgroup_on_subnet( subrec, reg_name); if(!work) { DEBUG(0,("become_logon_server_success: Error - cannot find \ diff --git a/source3/nmbd/nmbd_mynames.c b/source3/nmbd/nmbd_mynames.c index f02fbe1640..83a8361ed9 100644 --- a/source3/nmbd/nmbd_mynames.c +++ b/source3/nmbd/nmbd_mynames.c @@ -93,8 +93,8 @@ static void insert_refresh_name_into_unicast( struct subnet_record *subrec, } if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL) { - nstring name; - pull_ascii_nstring(name, nmbname->name); + fstring name; + pull_ascii_nstring(name, sizeof(name), nmbname->name); /* The name needs to be created on the unicast subnet. */ (void)add_name_to_subnet( unicast_subnet, name, nmbname->name_type, nb_type, diff --git a/source3/nmbd/nmbd_namelistdb.c b/source3/nmbd/nmbd_namelistdb.c index d1c9afd608..9f89abdbb2 100644 --- a/source3/nmbd/nmbd_namelistdb.c +++ b/source3/nmbd/nmbd_namelistdb.c @@ -45,13 +45,13 @@ void set_samba_nb_type(void) static void upcase_name( struct nmb_name *target, struct nmb_name *source ) { int i; - nstring targ; + fstring targ; fstring scope; if( NULL != source ) memcpy( target, source, sizeof( struct nmb_name ) ); - pull_ascii_nstring(targ, target->name); + pull_ascii_nstring(targ, sizeof(targ), target->name); strupper_m( targ ); push_ascii_nstring( target->name, targ); @@ -255,8 +255,8 @@ void standard_success_register(struct subnet_record *subrec, namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME ); if( NULL == namerec ) { - nstring name; - pull_ascii_nstring(name, nmbname->name); + fstring name; + pull_ascii_nstring(name, sizeof(name), nmbname->name); add_name_to_subnet( subrec, name, nmbname->name_type, nb_flags, ttl, SELF_NAME, 1, ®istered_ip ); } else { diff --git a/source3/nmbd/nmbd_nameregister.c b/source3/nmbd/nmbd_nameregister.c index 0397f56512..4fbdd143e1 100644 --- a/source3/nmbd/nmbd_nameregister.c +++ b/source3/nmbd/nmbd_nameregister.c @@ -85,8 +85,8 @@ static void register_name_response(struct subnet_record *subrec, */ #if 1 /* OLD_SAMBA_SERVER_HACK */ - nstring ans_name; - pull_ascii_nstring(ans_name, answer_name->name); + fstring ans_name; + pull_ascii_nstring(ans_name, sizeof(ans_name), answer_name->name); if((nmb->header.rcode == ACT_ERR) && strequal(lp_workgroup(), ans_name) && (answer_name->name_type == 0x1b)) { /* Pretend we did not get this. */ @@ -418,7 +418,7 @@ static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags, struct subnet_record *subrec; char **wins_tags; struct in_addr *ip_list; - nstring name; + fstring name; for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) ) num_ips++; @@ -434,7 +434,7 @@ static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags, ip_list[i] = subrec->myip; } - pull_ascii_nstring(name, nmbname->name); + pull_ascii_nstring(name, sizeof(name), nmbname->name); add_name_to_subnet(unicast_subnet, name, nmbname->name_type, nb_flags, lp_max_ttl(), SELF_NAME, num_ips, ip_list); @@ -473,17 +473,18 @@ void register_name(struct subnet_record *subrec, struct nmb_name nmbname; nstring nname; - if (strlen(name)+1 > sizeof(nstring)) { - memcpy(nname, name,sizeof(nstring)-1); - nname[sizeof(nstring)-1] = '\0'; + errno = 0; + push_ascii_nstring(nname, name); + if (errno == E2BIG) { + fstring tname; + pull_ascii_nstring(tname, sizeof(tname), nname); DEBUG(0,("register_name: NetBIOS name %s is too long. Truncating to %s\n", - name, nname)); + name, tname)); + make_nmb_name(&nmbname, tname, type); } else { - nstrcpy(nname,name); + make_nmb_name(&nmbname, name, type); } - make_nmb_name(&nmbname, nname, type); - /* Always set the NB_ACTIVE flag on the name we are registering. Doesn't make sense without it. */ diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c index c318689fd1..b5cbaab00b 100644 --- a/source3/nmbd/nmbd_packets.c +++ b/source3/nmbd/nmbd_packets.c @@ -1034,7 +1034,7 @@ static void process_browse_packet(struct packet_struct *p, char *buf,int len) int command = CVAL(buf,0); struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p); char scope[64]; - nstring src_name; + fstring src_name; /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */ pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE); @@ -1044,7 +1044,7 @@ mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope())); return; } - pull_ascii_nstring(src_name, dgram->source_name.name); + pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name); if (is_myname(src_name)) { DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \ %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name))); @@ -1121,7 +1121,7 @@ static void process_lanman_packet(struct packet_struct *p, char *buf,int len) int command = SVAL(buf,0); struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p); char scope[64]; - nstring src_name; + fstring src_name; /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */ @@ -1132,7 +1132,7 @@ mismatch with our scope (%s).\n", inet_ntoa(p->ip), scope, global_scope())); return; } - pull_ascii_nstring(src_name, dgram->source_name.name); + pull_ascii_nstring(src_name, sizeof(src_name), dgram->source_name.name); if (is_myname(src_name)) { DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \ %s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name))); diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index 13aefabd26..ff2aea6c08 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -141,7 +141,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); case QUERYFORPDC: { fstring mach_str, getdc_str; - nstring source_name; + fstring source_name; char *q = buf + 2; char *machine = q; @@ -220,7 +220,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", dump_data(4, outbuf, PTR_DIFF(q, outbuf)); pull_ascii_fstring(getdc_str, getdc); - pull_ascii_nstring(source_name, dgram->source_name.name); + pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); send_mailslot(True, getdc_str, outbuf,PTR_DIFF(q,outbuf), @@ -435,7 +435,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", dump_data(4, outbuf, PTR_DIFF(q, outbuf)); pull_ascii_fstring(getdc_str, getdc); - pull_ascii_nstring(source_name, dgram->source_name.name); + pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); send_mailslot(True, getdc, outbuf,PTR_DIFF(q,outbuf), diff --git a/source3/nmbd/nmbd_synclists.c b/source3/nmbd/nmbd_synclists.c index 6a0576a5a4..424af1e2e3 100644 --- a/source3/nmbd/nmbd_synclists.c +++ b/source3/nmbd/nmbd_synclists.c @@ -31,8 +31,8 @@ struct sync_record { struct sync_record *next, *prev; - nstring workgroup; - nstring server; + fstring workgroup; + fstring server; pstring fname; struct in_addr ip; pid_t pid; @@ -148,8 +148,8 @@ done: ZERO_STRUCTP(s); - nstrcpy(s->workgroup, work->work_group); - nstrcpy(s->server, name); + fstrcpy(s->workgroup, work->work_group); + fstrcpy(s->server, name); s->ip = ip; slprintf(s->fname, sizeof(pstring)-1, @@ -206,7 +206,7 @@ static void complete_one(struct sync_record *s, sname, lp_max_ttl()); if (work) { /* remember who the master is */ - nstrcpy(work->local_master_browser_name, comment); + fstrcpy(work->local_master_browser_name, comment); } } return; diff --git a/source3/nmbd/nmbd_winsproxy.c b/source3/nmbd/nmbd_winsproxy.c index bace112752..d91818698e 100644 --- a/source3/nmbd/nmbd_winsproxy.c +++ b/source3/nmbd/nmbd_winsproxy.c @@ -30,7 +30,7 @@ static void wins_proxy_name_query_request_success( struct subnet_record *subrec, struct userdata_struct *userdata, struct nmb_name *nmbname, struct in_addr ip, struct res_rec *rrec) { - nstring name; + fstring name; struct packet_struct *original_packet; struct subnet_record *orig_broadcast_subnet; struct name_record *namerec; @@ -73,7 +73,7 @@ returned for name %s.\n", nmb_namestr(nmbname) )); if(rrec == PERMANENT_TTL) ttl = lp_max_ttl(); - pull_ascii_nstring(name, nmbname->name); + pull_ascii_nstring(name, sizeof(name), nmbname->name); namerec = add_name_to_subnet( orig_broadcast_subnet, name, nmbname->name_type, nb_flags, ttl, WINS_PROXY_NAME, num_ips, iplist ); @@ -193,7 +193,7 @@ void make_wins_proxy_name_query_request( struct subnet_record *subrec, long *ud[(sizeof(struct userdata_struct) + sizeof(struct subrec *) + sizeof(struct packet_struct *))/sizeof(long *) + 1]; struct userdata_struct *userdata = (struct userdata_struct *)ud; - nstring qname; + fstring qname; memset(ud, '\0', sizeof(ud)); @@ -205,7 +205,7 @@ void make_wins_proxy_name_query_request( struct subnet_record *subrec, sizeof(struct packet_struct *)); /* Now use the unicast subnet to query the name with the WINS server. */ - pull_ascii_nstring(qname, question_name->name); + pull_ascii_nstring(qname, sizeof(qname), question_name->name); query_name( unicast_subnet, qname, question_name->name_type, wins_proxy_name_query_request_success, wins_proxy_name_query_request_fail, diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c index aae1cf633f..fd7718e2a6 100644 --- a/source3/nmbd/nmbd_winsserver.c +++ b/source3/nmbd/nmbd_winsserver.c @@ -744,7 +744,7 @@ querying for name %s in order to replace it and this reply.\n", nmb_namestr(ques void wins_process_name_registration_request(struct subnet_record *subrec, struct packet_struct *p) { - nstring name; + fstring name; struct nmb_packet *nmb = &p->packet.nmb; struct nmb_name *question = &nmb->question.question_name; BOOL bcast = nmb->header.nm_flags.bcast; @@ -906,7 +906,7 @@ already exists in WINS as a GROUP name.\n", nmb_namestr(question) )); */ if ( namerec != NULL ) - pull_ascii_nstring(name, namerec->name.name); + pull_ascii_nstring(name, sizeof(name), namerec->name.name); if( is_myname(name) ) { if(!ismyip(from_ip)) { @@ -983,7 +983,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio * code. JRA. */ - pull_ascii_nstring(name, question->name); + pull_ascii_nstring(name, sizeof(name), question->name); query_name_from_wins_server( *namerec->data.ip, name, question->name_type, @@ -997,7 +997,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio * Name did not exist - add it. */ - pull_ascii_nstring(name, question->name); + pull_ascii_nstring(name, sizeof(name), question->name); add_name_to_subnet( subrec, name, question->name_type, nb_flags, ttl, REGISTER_NAME, 1, &from_ip); @@ -1119,7 +1119,7 @@ void wins_process_multihomed_name_registration_request( struct subnet_record *su struct in_addr from_ip; BOOL group = (nb_flags & NB_GROUP) ? True : False; struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0"); - nstring qname; + fstring qname; putip((char *)&from_ip,&nmb->additional->rdata[2]); @@ -1318,7 +1318,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio * not the person who sent the packet */ - pull_ascii_nstring( qname, question->name); + pull_ascii_nstring( qname, sizeof(qname), question->name); query_name_from_wins_server( namerec->data.ip[0], qname, question->name_type, @@ -1333,7 +1333,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio * Name did not exist - add it. */ - pull_ascii_nstring( qname, question->name); + pull_ascii_nstring( qname, sizeof(qname), question->name); add_name_to_subnet( subrec, qname, question->name_type, nb_flags, ttl, REGISTER_NAME, 1, &from_ip); @@ -1479,7 +1479,7 @@ void wins_process_name_query_request(struct subnet_record *subrec, struct nmb_packet *nmb = &p->packet.nmb; struct nmb_name *question = &nmb->question.question_name; struct name_record *namerec = NULL; - nstring qname; + fstring qname; DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n", nmb_namestr(question), inet_ntoa(p->ip) )); @@ -1491,7 +1491,7 @@ void wins_process_name_query_request(struct subnet_record *subrec, * to discover other domains that may not have a presence on their subnet. */ - pull_ascii_nstring(qname, question->name); + pull_ascii_nstring(qname, sizeof(qname), question->name); if(strequal( qname, "*") && (question->name_type == 0x1b)) { process_wins_dmb_query_request( subrec, p); return; @@ -1845,8 +1845,8 @@ void wins_write_database(BOOL background) DEBUGADD(4,("%2x\n", namerec->data.nb_flags )); if( namerec->data.source == REGISTER_NAME ) { - nstring name; - pull_ascii_nstring(name, namerec->name.name); + fstring name; + pull_ascii_nstring(name, sizeof(name), namerec->name.name); x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */ (int)namerec->data.death_time); diff --git a/source3/nmbd/nmbd_workgroupdb.c b/source3/nmbd/nmbd_workgroupdb.c index b9fab4b278..bd2737ef97 100644 --- a/source3/nmbd/nmbd_workgroupdb.c +++ b/source3/nmbd/nmbd_workgroupdb.c @@ -48,6 +48,8 @@ static struct work_record *create_workgroup(const char *name, int ttl) { struct work_record *work; struct subnet_record *subrec; + nstring nname; + int t = -1; if((work = (struct work_record *)malloc(sizeof(*work))) == NULL) { @@ -55,15 +57,18 @@ static struct work_record *create_workgroup(const char *name, int ttl) return NULL; } memset((char *)work, '\0', sizeof(*work)); - - if (strlen(name)+1 > sizeof(nstring)) { - memcpy(work->work_group,name,sizeof(nstring)-1); - work->work_group[sizeof(nstring)-1] = '\0'; - DEBUG(0,("create_workgroup: workgroup name %s is too long. Truncating to %s\n", - name, work->work_group )); - } else { - nstrcpy(work->work_group,name); - } + + errno = 0; + push_ascii_nstring(nname, name); + if (errno == E2BIG) { + fstring tname; + pull_ascii_nstring(tname, sizeof(tname), nname); + fstrcpy(work->work_group,tname); + DEBUG(0,("create_workgroup: workgroup name %s is too long. Truncating to %s\n", + name, tname)); + } else { + fstrcpy(work->work_group,name); + } work->serverlist = NULL; work->RunningElection = False; diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index 28e3cf97d1..96961368fb 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -169,6 +169,8 @@ static int reply_lanman2(char *inbuf, char *outbuf) static int negprot_spnego(char *p) { DATA_BLOB blob; + nstring dos_name; + fstring unix_name; uint8 guid[17]; const char *OIDs_krb5[] = {OID_KERBEROS5, OID_KERBEROS5_OLD, @@ -181,7 +183,11 @@ static int negprot_spnego(char *p) global_spnego_negotiated = True; ZERO_STRUCT(guid); - safe_strcpy((char *)guid, global_myname(), sizeof(guid)-1); + + safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1); + strlower_m(unix_name); + push_ascii_nstring(dos_name, unix_name); + safe_strcpy((char *)guid, dos_name, sizeof(guid)-1); #ifdef DEVELOPER /* valgrind fixer... */ @@ -192,8 +198,6 @@ static int negprot_spnego(char *p) } #endif - strlower_m((char *)guid); - #if 0 /* strangely enough, NT does not sent the single OID NTLMSSP when not a ADS member, it sends no OIDs at all -- cgit From 309c0a65b7de7311a5032d6a8e41c9eb039af2aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Mar 2004 02:47:19 +0000 Subject: Ensure we don't truncate strcmps to nstring anymore... Jeremy. (This used to be commit b3aff7f214da97925690a5d0a887ea1b336d107a) --- source3/lib/charcnv.c | 2 ++ source3/libsmb/nmblib.c | 5 ++++- source3/nmbd/nmbd_browsesync.c | 4 ++-- source3/nmbd/nmbd_elections.c | 8 ++++---- source3/nmbd/nmbd_serverlistdb.c | 2 +- source3/nmbd/nmbd_workgroupdb.c | 6 +++--- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index d38bfdb534..c2213c966d 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -833,6 +833,7 @@ size_t push_ascii_nstring(void *dest, const char *src) size_t i, buffer_len, dest_len; smb_ucs2_t *buffer; + conv_silent = True; buffer_len = push_ucs2_allocate(&buffer, src); if (buffer_len == (size_t)-1) { smb_panic("failed to create UCS2 buffer"); @@ -854,6 +855,7 @@ size_t push_ascii_nstring(void *dest, const char *src) ((char *)dest)[dest_len] = '\0'; SAFE_FREE(buffer); + conv_silent = False; return dest_len; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index bc2cca0e0e..3c25eba744 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -855,8 +855,11 @@ static int build_dgram(char *buf,struct packet_struct *p) void make_nmb_name( struct nmb_name *n, const char *name, int type) { + fstring unix_name; memset( (char *)n, '\0', sizeof(struct nmb_name) ); - push_ascii(n->name, name, sizeof(n->name), STR_TERMINATE|STR_UPPER); + fstrcpy(unix_name, name); + strupper_m(unix_name); + push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE); n->name_type = (unsigned int)type & 0xFF; push_ascii(n->scope, global_scope(), 64, STR_TERMINATE); } diff --git a/source3/nmbd/nmbd_browsesync.c b/source3/nmbd/nmbd_browsesync.c index 454c349767..f16d8603c9 100644 --- a/source3/nmbd/nmbd_browsesync.c +++ b/source3/nmbd/nmbd_browsesync.c @@ -639,14 +639,14 @@ void sync_all_dmbs(time_t t) /* count how many syncs we might need to do */ for (work=unicast_subnet->workgrouplist; work; work = work->next) { - if (strncmp(lp_workgroup(), work->work_group, sizeof(nstring))) { + if (strcmp(lp_workgroup(), work->work_group)) { count++; } } /* sync with a probability of 1/count */ for (work=unicast_subnet->workgrouplist; work; work = work->next) { - if (strncmp(lp_workgroup(), work->work_group, sizeof(nstring))) { + if (strcmp(lp_workgroup(), work->work_group)) { fstring dmb_name; if (((unsigned)sys_random()) % count != 0) diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c index 882c26ce80..24026d7cd9 100644 --- a/source3/nmbd/nmbd_elections.c +++ b/source3/nmbd/nmbd_elections.c @@ -97,7 +97,7 @@ static void check_for_master_browser_fail( struct subnet_record *subrec, return; } - if (strnequal(work->work_group, lp_workgroup(), sizeof(nstring)-1)) { + if (strequal(work->work_group, lp_workgroup())) { if (lp_local_master()) { /* We have discovered that there is no local master @@ -145,7 +145,7 @@ void check_master_browser_exists(time_t t) struct work_record *work; for (work = subrec->workgrouplist; work; work = work->next) { - if (strnequal(work->work_group, workgroup_name, sizeof(nstring)-1) && !AM_LOCAL_MASTER_BROWSER(work)) { + if (strequal(work->work_group, workgroup_name) && !AM_LOCAL_MASTER_BROWSER(work)) { /* Do a name query for the local master browser on this net. */ query_name( subrec, work->work_group, 0x1d, check_for_master_browser_success, @@ -284,7 +284,7 @@ void process_election(struct subnet_record *subrec, struct packet_struct *p, cha goto done; } - if (!strnequal(work->work_group, lp_workgroup(), sizeof(nstring)-1)) { + if (!strequal(work->work_group, lp_workgroup())) { DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \ is not my workgroup.\n", work->work_group, subrec->subnet_name )); goto done; @@ -381,7 +381,7 @@ void nmbd_message_election(int msg_type, pid_t src, void *buf, size_t len) for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { struct work_record *work; for (work = subrec->workgrouplist; work; work = work->next) { - if (strnequal(work->work_group, lp_workgroup(), sizeof(nstring)-1)) { + if (strequal(work->work_group, lp_workgroup())) { work->needelection = True; work->ElectionCount=0; work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE; diff --git a/source3/nmbd/nmbd_serverlistdb.c b/source3/nmbd/nmbd_serverlistdb.c index cdb1089a54..e6fad8319d 100644 --- a/source3/nmbd/nmbd_serverlistdb.c +++ b/source3/nmbd/nmbd_serverlistdb.c @@ -251,7 +251,7 @@ static uint32 write_this_workgroup_name( struct subnet_record *subrec, { struct subnet_record *ssub; - if(strnequal(lp_workgroup(), work->work_group, sizeof(nstring)-1)) + if(strequal(lp_workgroup(), work->work_group)) return 0; /* This is a workgroup we have seen on a broadcast subnet. All diff --git a/source3/nmbd/nmbd_workgroupdb.c b/source3/nmbd/nmbd_workgroupdb.c index bd2737ef97..3efef49c04 100644 --- a/source3/nmbd/nmbd_workgroupdb.c +++ b/source3/nmbd/nmbd_workgroupdb.c @@ -88,7 +88,7 @@ static struct work_record *create_workgroup(const char *name, int ttl) for (subrec = FIRST_SUBNET; subrec && (t == -1); subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) { struct work_record *w; for (w = subrec->workgrouplist; w && t == -1; w = w->next) { - if (strnequal(w->work_group, work->work_group, sizeof(nstring)-1)) + if (strequal(w->work_group, work->work_group)) t = w->token; } } @@ -162,7 +162,7 @@ struct work_record *find_workgroup_on_subnet(struct subnet_record *subrec, name, subrec->subnet_name)); for (ret = subrec->workgrouplist; ret; ret = ret->next) { - if (strnequal(ret->work_group,name,sizeof(nstring)-1)) { + if (strequal(ret->work_group,name)) { DEBUGADD(4, ("found.\n")); return(ret); } @@ -223,7 +223,7 @@ void initiate_myworkgroup_startup(struct subnet_record *subrec, struct work_reco { int i; - if(!strnequal(lp_workgroup(), work->work_group,sizeof(nstring)-1)) + if(!strequal(lp_workgroup(), work->work_group)) return; /* If this is a broadcast subnet then start elections on it if we are so configured. */ -- cgit From 146d674c2ce78ddb2e3e5a63ad4f2e53b52d093e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Mar 2004 16:30:39 +0000 Subject: Add find_alias, create_alias, delete_alias, get_aliasinfo, set_aliasinfo and enum_aliases to passdb. create and delete are not yet filled, you have to do this with net groupmap and net idmap restore. Volker (This used to be commit f44bf63d1143ddf6a1a2fdc15a301e0dc0840d50) --- source3/groupdb/mapping.c | 109 +++++++++++++++++++++++++ source3/include/ntdomain.h | 7 -- source3/include/passdb.h | 53 +++++++++++- source3/passdb/pdb_interface.c | 178 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 339 insertions(+), 8 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 48bdfe2cd2..818a4acb84 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -1270,6 +1270,115 @@ NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods, NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } +NTSTATUS pdb_default_find_alias(struct pdb_methods *methods, + const char *name, DOM_SID *sid) +{ + GROUP_MAP map; + + if (!get_group_map_from_ntname(name, &map)) + return NT_STATUS_NO_SUCH_ALIAS; + + if ((map.sid_name_use != SID_NAME_WKN_GRP) && + (map.sid_name_use != SID_NAME_ALIAS)) + return NT_STATUS_OBJECT_TYPE_MISMATCH; + + sid_copy(sid, &map.sid); + return NT_STATUS_OK; +} + +NTSTATUS pdb_default_create_alias(struct pdb_methods *methods, + const char *name, uint32 *rid) +{ + return NT_STATUS_ACCESS_DENIED; +} + +NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods, + const DOM_SID *sid) +{ + return NT_STATUS_ACCESS_DENIED; +} + +NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods, + const DOM_SID *sid, + uint32 start_idx, uint32 max_entries, + uint32 *num_aliases, + struct acct_info **info) +{ + extern DOM_SID global_sid_Builtin; + + GROUP_MAP *map; + int i, num_maps; + enum SID_NAME_USE type = SID_NAME_UNKNOWN; + + if (sid_compare(sid, get_global_sam_sid()) == 0) + type = SID_NAME_ALIAS; + + if (sid_compare(sid, &global_sid_Builtin) == 0) + type = SID_NAME_WKN_GRP; + + if (!enum_group_mapping(type, &map, &num_maps, False) || + (num_maps == 0)) { + *num_aliases = 0; + *info = NULL; + goto done; + } + + if (start_idx > num_maps) { + *num_aliases = 0; + *info = NULL; + goto done; + } + + *num_aliases = num_maps - start_idx; + + if (*num_aliases > max_entries) + *num_aliases = max_entries; + + *info = malloc(sizeof(struct acct_info) * (*num_aliases)); + + for (i=0; i<*num_aliases; i++) { + fstrcpy((*info)[i].acct_name, map[i+start_idx].nt_name); + fstrcpy((*info)[i].acct_desc, map[i+start_idx].comment); + sid_peek_rid(&map[i].sid, &(*info)[i+start_idx].rid); + } + + done: + SAFE_FREE(map); + return NT_STATUS_OK; +} + +NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods, + const DOM_SID *sid, + struct acct_info *info) +{ + GROUP_MAP map; + + if (!get_group_map_from_sid(*sid, &map)) + return NT_STATUS_NO_SUCH_ALIAS; + + fstrcpy(info->acct_name, map.nt_name); + fstrcpy(info->acct_desc, map.comment); + sid_peek_rid(&map.sid, &info->rid); + return NT_STATUS_OK; +} + +NTSTATUS pdb_default_set_aliasinfo(struct pdb_methods *methods, + const DOM_SID *sid, + struct acct_info *info) +{ + GROUP_MAP map; + + if (!get_group_map_from_sid(*sid, &map)) + return NT_STATUS_NO_SUCH_ALIAS; + + fstrcpy(map.comment, info->acct_desc); + + if (!add_mapping_entry(&map, TDB_REPLACE)) + return NT_STATUS_ACCESS_DENIED; + + return NT_STATUS_OK; +} + NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods, enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, int *num_entries, diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index eaedc7ea9b..4e6795a85d 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -382,13 +382,6 @@ typedef struct } rid_name; -struct acct_info -{ - fstring acct_name; /* account name */ - fstring acct_desc; /* account name */ - uint32 rid; /* domain-relative RID */ -}; - /* * higher order functions for use with msrpc client code */ diff --git a/source3/include/passdb.h b/source3/include/passdb.h index df7c969633..21feb7208f 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -232,6 +232,12 @@ typedef struct _GROUP_INFO { fstring comment; } GROUP_INFO; +struct acct_info +{ + fstring acct_name; /* account name */ + fstring acct_desc; /* account name */ + uint32 rid; /* domain-relative RID */ +}; typedef struct sam_trust_passwd { TALLOC_CTX *mem_ctx; @@ -262,7 +268,7 @@ typedef struct sam_trust_passwd { * this SAMBA will load. Increment this if *ANY* changes are made to the interface. */ -#define PASSDB_INTERFACE_VERSION 6 +#define PASSDB_INTERFACE_VERSION 7 typedef struct pdb_context { @@ -310,6 +316,29 @@ typedef struct pdb_context GROUP_MAP **rmap, int *num_entries, BOOL unix_only); + NTSTATUS (*pdb_find_alias)(struct pdb_context *context, + const char *name, DOM_SID *sid); + + NTSTATUS (*pdb_create_alias)(struct pdb_context *context, + const char *name, uint32 *rid); + + NTSTATUS (*pdb_delete_alias)(struct pdb_context *context, + const DOM_SID *sid); + + NTSTATUS (*pdb_enum_aliases)(struct pdb_context *context, + const DOM_SID *domain_sid, + uint32 start_idx, uint32 num_entries, + uint32 *num_aliases, + struct acct_info **aliases); + + NTSTATUS (*pdb_get_aliasinfo)(struct pdb_context *context, + const DOM_SID *sid, + struct acct_info *info); + + NTSTATUS (*pdb_set_aliasinfo)(struct pdb_context *context, + const DOM_SID *sid, + struct acct_info *info); + NTSTATUS (*pdb_add_aliasmem)(struct pdb_context *context, const DOM_SID *alias, const DOM_SID *member); @@ -430,6 +459,28 @@ typedef struct pdb_methods GROUP_MAP **rmap, int *num_entries, BOOL unix_only); + NTSTATUS (*find_alias)(struct pdb_methods *methods, + const char *name, DOM_SID *sid); + + NTSTATUS (*create_alias)(struct pdb_methods *methods, + const char *name, uint32 *rid); + + NTSTATUS (*delete_alias)(struct pdb_methods *methods, + const DOM_SID *sid); + + NTSTATUS (*enum_aliases)(struct pdb_methods *methods, + const DOM_SID *domain_sid, + uint32 start_idx, uint32 max_entries, + uint32 *num_aliases, struct acct_info **info); + + NTSTATUS (*get_aliasinfo)(struct pdb_methods *methods, + const DOM_SID *sid, + struct acct_info *info); + + NTSTATUS (*set_aliasinfo)(struct pdb_methods *methods, + const DOM_SID *sid, + struct acct_info *info); + NTSTATUS (*add_aliasmem)(struct pdb_methods *methods, const DOM_SID *alias, const DOM_SID *member); NTSTATUS (*del_aliasmem)(struct pdb_methods *methods, diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 5679d4a5e8..e4a275fe08 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -426,6 +426,95 @@ static NTSTATUS context_enum_group_mapping(struct pdb_context *context, num_entries, unix_only); } +static NTSTATUS context_find_alias(struct pdb_context *context, + const char *name, DOM_SID *sid) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + if ((!context) || (!context->pdb_methods)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods->find_alias(context->pdb_methods, + name, sid); +} + +static NTSTATUS context_create_alias(struct pdb_context *context, + const char *name, uint32 *rid) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + if ((!context) || (!context->pdb_methods)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods->create_alias(context->pdb_methods, + name, rid); +} + +static NTSTATUS context_delete_alias(struct pdb_context *context, + const DOM_SID *sid) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + if ((!context) || (!context->pdb_methods)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods->delete_alias(context->pdb_methods, sid); +} + +static NTSTATUS context_enum_aliases(struct pdb_context *context, + const DOM_SID *sid, + uint32 start_idx, uint32 max_entries, + uint32 *num_aliases, + struct acct_info **info) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + if ((!context) || (!context->pdb_methods)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods->enum_aliases(context->pdb_methods, + sid, start_idx, max_entries, + num_aliases, info); +} + +static NTSTATUS context_get_aliasinfo(struct pdb_context *context, + const DOM_SID *sid, + struct acct_info *info) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + if ((!context) || (!context->pdb_methods)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods->get_aliasinfo(context->pdb_methods, + sid, info); +} + +static NTSTATUS context_set_aliasinfo(struct pdb_context *context, + const DOM_SID *sid, + struct acct_info *info) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + if ((!context) || (!context->pdb_methods)) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + return context->pdb_methods->set_aliasinfo(context->pdb_methods, + sid, info); +} + static NTSTATUS context_add_aliasmem(struct pdb_context *context, const DOM_SID *alias, const DOM_SID *member) @@ -834,6 +923,12 @@ static NTSTATUS make_pdb_context(struct pdb_context **context) (*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry; (*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry; (*context)->pdb_enum_group_mapping = context_enum_group_mapping; + (*context)->pdb_find_alias = context_find_alias; + (*context)->pdb_create_alias = context_create_alias; + (*context)->pdb_delete_alias = context_delete_alias; + (*context)->pdb_enum_aliases = context_enum_aliases; + (*context)->pdb_get_aliasinfo = context_get_aliasinfo; + (*context)->pdb_set_aliasinfo = context_set_aliasinfo; (*context)->pdb_add_aliasmem = context_add_aliasmem; (*context)->pdb_del_aliasmem = context_del_aliasmem; (*context)->pdb_enum_aliasmem = context_enum_aliasmem; @@ -1158,6 +1253,83 @@ BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, rmap, num_entries, unix_only)); } +BOOL pdb_find_alias(const char *name, DOM_SID *sid) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context->pdb_find_alias(pdb_context, + name, sid)); +} + +BOOL pdb_create_alias(const char *name, uint32 *rid) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context->pdb_create_alias(pdb_context, + name, rid)); +} + +BOOL pdb_delete_alias(const DOM_SID *sid) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context->pdb_delete_alias(pdb_context, + sid)); + +} + +BOOL pdb_enum_aliases(const DOM_SID *sid, uint32 start_idx, uint32 max_entries, + uint32 *num_aliases, struct acct_info **info) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context->pdb_enum_aliases(pdb_context, sid, + start_idx, + max_entries, + num_aliases, + info)); +} + +BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context->pdb_get_aliasinfo(pdb_context, sid, + info)); +} + +BOOL pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return False; + } + + return NT_STATUS_IS_OK(pdb_context->pdb_set_aliasinfo(pdb_context, sid, + info)); +} + BOOL pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member) { struct pdb_context *pdb_context = pdb_get_static_context(False); @@ -1401,6 +1573,12 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry; (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry; (*methods)->enum_group_mapping = pdb_default_enum_group_mapping; + (*methods)->find_alias = pdb_default_find_alias; + (*methods)->create_alias = pdb_default_create_alias; + (*methods)->delete_alias = pdb_default_delete_alias; + (*methods)->enum_aliases = pdb_default_enum_aliases; + (*methods)->get_aliasinfo = pdb_default_get_aliasinfo; + (*methods)->set_aliasinfo = pdb_default_set_aliasinfo; (*methods)->add_aliasmem = pdb_default_add_aliasmem; (*methods)->del_aliasmem = pdb_default_del_aliasmem; (*methods)->enum_aliasmem = pdb_default_enum_aliasmem; -- cgit From ebd5fe9d02433c5bfe480ae09385ddd3f7e2364c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Mar 2004 16:43:25 +0000 Subject: Remove the prototype for alias support in winbind again. This will be replaced by a winbindd_passdb.c checkin soon. Volker (This used to be commit 4e96b46a8481bdf4f3408574ccc8c921ade7018b) --- source3/nsswitch/winbindd.h | 5 - source3/nsswitch/winbindd_acct.c | 204 -------------------------------------- source3/nsswitch/winbindd_group.c | 144 ++++++--------------------- 3 files changed, 29 insertions(+), 324 deletions(-) diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index cece2b40de..0087d58195 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -48,11 +48,6 @@ struct winbindd_cli_state { struct winbindd_response response; /* Respose to client */ struct getent_state *getpwent_state; /* State for getpwent() */ struct getent_state *getgrent_state; /* State for getgrent() */ - - /* Local groups for getgrent() */ - char **local_group_names; - int num_local_group_names; - int local_group_ndx; }; /* State between get{pw,gr}ent() calls */ diff --git a/source3/nsswitch/winbindd_acct.c b/source3/nsswitch/winbindd_acct.c index be3f1405e4..e6496695cb 100644 --- a/source3/nsswitch/winbindd_acct.c +++ b/source3/nsswitch/winbindd_acct.c @@ -174,158 +174,6 @@ static char* passwd2string( const WINBINDD_PW *pw ) return string; } -static void -add_member(const char *domain, const char *user, - char ***members, int *num_members) -{ - fstring name; - - fill_domain_username(name, domain, user); - - *members = Realloc(*members, (*num_members+1) * sizeof(char **)); - - if (members == NULL) { - DEBUG(10, ("Realloc failed\n")); - return; - } - - (*members)[*num_members] = strdup(name); - *num_members += 1; -} - -/********************************************************************** - Add member users resulting from sid. Expand if it is a domain group. -**********************************************************************/ - -static void -add_expanded_sid(DOM_SID *sid, char ***members, int *num_members) -{ - DOM_SID dom_sid; - uint32 rid; - struct winbindd_domain *domain; - int i; - - char *name = NULL; - enum SID_NAME_USE type; - - uint32 num_names; - DOM_SID **sid_mem; - char **names; - uint32 *types; - - NTSTATUS result; - - TALLOC_CTX *mem_ctx = talloc_init("add_expanded_sid"); - - if (mem_ctx == NULL) { - DEBUG(1, ("talloc_init failed\n")); - return; - } - - sid_copy(&dom_sid, sid); - sid_split_rid(&dom_sid, &rid); - - domain = find_domain_from_sid(&dom_sid); - - if (domain == NULL) { - DEBUG(3, ("Could not find domain for sid %s\n", - sid_string_static(sid))); - goto done; - } - - result = domain->methods->sid_to_name(domain, mem_ctx, sid, - &name, &type); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(3, ("sid_to_name failed for sid %s\n", - sid_string_static(sid))); - goto done; - } - - DEBUG(10, ("Found name %s, type %d\n", name, type)); - - if (type == SID_NAME_USER) { - add_member(domain->name, name, members, num_members); - goto done; - } - - if (type != SID_NAME_DOM_GRP) { - DEBUG(10, ("Alias member %s neither user nor group, ignore\n", - name)); - goto done; - } - - /* Expand the domain group */ - - result = domain->methods->lookup_groupmem(domain, mem_ctx, - sid, &num_names, - &sid_mem, &names, - &types); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(10, ("Could not lookup group members for %s: %s\n", - name, nt_errstr(result))); - goto done; - } - - for (i=0; iname, names[i], members, num_members); - } - - done: - talloc_destroy(mem_ctx); - return; -} - -/********************************************************************** - Add alias members. Expand them if they are domain groups. -**********************************************************************/ - -static void -add_expanded_alias_members(gid_t gid, char ***members, int *num_members) -{ - GROUP_MAP map; - DOM_SID *sids = NULL; - int i, num_sids; - - if (!pdb_getgrgid(&map, gid)) { - DEBUG(10, ("No mapping for group %d\n", gid)); - return; - } - - if ( (map.sid_name_use != SID_NAME_WKN_GRP) && - (map.sid_name_use != SID_NAME_ALIAS) ) { - DEBUG(10, ("Group %d is no alias\n", gid)); - return; - } - - if (!pdb_enum_aliasmem(&map.sid, &sids, &num_sids)) { - DEBUG(10, ("Could not enum aliases for group sid %s\n", - sid_string_static(&map.sid))); - return; - } - - for (i=0; inode_key.dptr; - - DEBUG(10, ("Found key %s\n", name)); - node = node->next; - /* Skip WBA_GROUP */ - name = strchr(name, '/'); - if (name == NULL) - continue; - name += 1; - - /* Skip NAME */ - name = strchr(name, '/'); - if (name == NULL) - continue; - name += 1; - - DEBUG(10, ("adding %s\n", name)); - - add_string_to_array(strdup(name), names, num_names); - } - - tdb_search_list_free(nodes); -} diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index d09b4ec6f9..4805e628dd 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -423,15 +423,6 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) free_getent_state(state->getgrent_state); state->getgrent_state = NULL; } - - /* Add our locally defined groups */ - - state->local_group_names = NULL; - state->num_local_group_names = 0; - state->local_group_ndx = 0; - - wb_list_group_names(&state->local_group_names, - &state->num_local_group_names); /* Create sam pipes for each domain we know about */ @@ -480,80 +471,6 @@ enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state) return WINBINDD_OK; } -/* Fetch group entries from local faked database */ - -static BOOL return_local_winbind_groups(struct winbindd_cli_state *state) -{ - WINBINDD_GR *grp; - char *buffer = NULL; - char *name; - int gr_mem_list_len = 0; - struct winbindd_gr *group_list; - struct winbindd_gr *gr; - - if (state->local_group_names == NULL) - return False; - - name = state->local_group_names[state->local_group_ndx]; - grp = wb_getgrnam(name); - - if (grp == NULL) { - DEBUG(3, ("Group %s vanished\n", name)); - - /* Stop that stuff.. */ - state->local_group_ndx = state->num_local_group_names; - - return False; - } - - gr_mem_list_len = gr_mem_buffer( &buffer, grp->gr_mem, grp->num_gr_mem ); - - state->response.extra_data = malloc(sizeof(struct winbindd_gr) + - gr_mem_list_len); - state->response.length += sizeof(struct winbindd_gr) + gr_mem_list_len; - - group_list = (struct winbindd_gr *)state->response.extra_data; - - if (group_list == NULL) { - DEBUG(0, ("Could not malloc group_list\n")); - return False; - } - - gr = &group_list[0]; - - ZERO_STRUCTP(gr); - - gr->gr_gid = grp->gr_gid; - safe_strcpy(gr->gr_name, name, sizeof(gr->gr_name) - 1); - safe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1); - gr->num_gr_mem = grp->num_gr_mem; - gr->gr_mem_ofs = 0; - - memcpy(&((char *)state->response.extra_data) - [sizeof(struct winbindd_gr)], - buffer, gr_mem_list_len); - - SAFE_FREE(buffer); - SAFE_FREE(grp->gr_mem); - - state->response.data.num_entries = 1; - - state->local_group_ndx += 1; - - if (state->local_group_ndx >= state->num_local_group_names) { - int i; - - for (i=0; inum_local_group_names; i++) { - free(state->local_group_names[i]); - } - free(state->local_group_names); - state->local_group_names = NULL; - } - - return True; -} - - /* Get the list of domain groups and domain aliases for a domain. We fill in the sam_entries and num_sam_entries fields with domain group information. The dispinfo_ndx field is incremented to the index of the next group to @@ -689,9 +606,6 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) if (!lp_winbind_enum_groups()) return WINBINDD_ERROR; - if (return_local_winbind_groups(state)) - return WINBINDD_OK; - num_groups = MIN(MAX_GETGRENT_GROUPS, state->request.data.num_entries); if ((state->response.extra_data = @@ -982,20 +896,6 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) return WINBINDD_OK; } -static void add_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num) -{ - gid_t gid; - - DEBUG(10, ("Adding gids from SID: %s\n", sid_string_static(sid))); - - if (NT_STATUS_IS_OK(idmap_sid_to_gid(sid, &gid, 0))) - add_gid_to_array_unique(gid, gids, num); - - /* Add nested group memberships */ - - add_foreign_gids_from_sid(sid, gids, num); -} - /* Get user supplementary groups. This is much quicker than trying to invert the groups database. We merge the groups from the gids and other_sids info3 fields as trusted domain, universal group @@ -1013,7 +913,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) DOM_SID **user_grpsids; struct winbindd_domain *domain; enum winbindd_result result = WINBINDD_ERROR; - gid_t *gid_list = NULL; + gid_t *gid_list; unsigned int i; TALLOC_CTX *mem_ctx; NET_USER_INFO_3 *info3 = NULL; @@ -1061,8 +961,6 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; } - add_gids_from_sid(&user_sid, &gid_list, &num_gids); - /* Treat the info3 cache as authoritative as the lookup_usergroups() function may return cached data. */ @@ -1072,6 +970,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) info3->num_groups2, info3->num_other_sids)); num_groups = info3->num_other_sids + info3->num_groups2; + gid_list = calloc(sizeof(gid_t), num_groups); /* Go through each other sid and convert it to a gid */ @@ -1105,11 +1004,23 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) continue; } - add_gids_from_sid(&info3->other_sids[i].sid, - &gid_list, &num_gids); + /* Map to a gid */ - if (gid_list == NULL) - goto done; + 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))); + continue; + } + + /* We've jumped through a lot of hoops to get here */ + + DEBUG(10, ("winbindd_getgroups: mapped other sid %s to " + "gid %lu\n", sid_string_static( + &info3->other_sids[i].sid), + (unsigned long)gid_list[num_gids])); + + num_gids++; } for (i = 0; i < info3->num_groups2; i++) { @@ -1119,10 +1030,12 @@ 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 ); - add_gids_from_sid(&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))); + } - if (gid_list == NULL) - goto done; + num_gids++; } SAFE_FREE(info3); @@ -1140,11 +1053,12 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; for (i = 0; i < num_groups; i++) { - add_gids_from_sid(user_grpsids[i], - &gid_list, &num_gids); - - if (gid_list == NULL) - goto done; + 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; + } + num_gids++; } } -- cgit From 9522e181d1537bb4ec5e1d39ee4fb5034d07be20 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Mar 2004 17:35:47 +0000 Subject: Add alias support to winbindd_passdb. Sorry, Simo, this does not leave too much of your winbindd_passdb, users are currently not provided by that, only aliases. Currently the code to maintain that stuff is not yet in, this will be next, see my next posting to samba-technical. Volker (This used to be commit 9e0fb457ba77a55f8271b6acc91a07f0a8df3760) --- source3/nsswitch/winbindd.h | 1 + source3/nsswitch/winbindd_group.c | 16 +- source3/nsswitch/winbindd_passdb.c | 387 ++++++++++++++++++------------------- source3/nsswitch/winbindd_sid.c | 13 +- source3/nsswitch/winbindd_util.c | 23 ++- 5 files changed, 219 insertions(+), 221 deletions(-) diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 0087d58195..5c05a1b045 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -97,6 +97,7 @@ struct winbindd_domain { BOOL native_mode; /* is this a win2k domain in native mode ? */ BOOL active_directory; /* is this a win2k active directory ? */ BOOL primary; /* is this our primary domain ? */ + BOOL internal; /* BUILTIN and member SAM */ /* Lookup methods for this domain (LDAP or RPC) */ struct winbindd_methods *methods; diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 4805e628dd..94bd0fa0b9 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -104,6 +104,15 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain, DEBUG(10, ("group SID %s\n", sid_to_string(sid_string, group_sid))); *num_gr_mem = 0; + + /* HACK ALERT!! This whole routine does not cope with group members + * from more than one domain, ie aliases. Thus we have to work it out + * ourselves in a special routine. */ + + if (domain->internal) + return fill_passdb_alias_grmem(domain, group_sid, + num_gr_mem, + gr_mem, gr_mem_len); if ( !((group_name_type==SID_NAME_DOM_GRP) || ((group_name_type==SID_NAME_ALIAS) && domain->primary)) ) @@ -376,7 +385,8 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) } if ( !((name_type==SID_NAME_DOM_GRP) || - ((name_type==SID_NAME_ALIAS) && domain->primary) )) + ((name_type==SID_NAME_ALIAS) && domain->primary) || + ((name_type==SID_NAME_ALIAS) && domain->internal)) ) { DEBUG(1, ("name '%s' is not a local or domain group: %d\n", group_name, name_type)); @@ -539,8 +549,8 @@ static BOOL get_sam_group_entries(struct getent_state *ent) /* get the domain local groups if we are a member of a native win2k domain and are not using LDAP to get the groups */ - if ( lp_security() != SEC_ADS && domain->native_mode - && domain->primary ) + if ( ( lp_security() != SEC_ADS && domain->native_mode + && domain->primary) || domain->internal ) { DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n")); diff --git a/source3/nsswitch/winbindd_passdb.c b/source3/nsswitch/winbindd_passdb.c index 503b97899c..36f5297efe 100644 --- a/source3/nsswitch/winbindd_passdb.c +++ b/source3/nsswitch/winbindd_passdb.c @@ -5,6 +5,7 @@ Copyright (C) Tim Potter 2000-2001,2003 Copyright (C) Simo Sorce 2003 + Copyright (C) Volker Lendecke 2004 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 @@ -21,84 +22,161 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" #include "winbindd.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND +static void +add_member(const char *domain, const char *user, + char **members, int *num_members) +{ + fstring name; -/* Query display info for a domain. This returns enough information plus a - bit extra to give an overview of domain users for the User Manager - application. */ -static NTSTATUS query_user_list(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 *num_entries, - WINBIND_USERINFO **info) + fill_domain_username(name, domain, user); + safe_strcat(name, ",", sizeof(name)-1); + string_append(members, name); + *num_members += 1; +} + +/********************************************************************** + Add member users resulting from sid. Expand if it is a domain group. +**********************************************************************/ + +static void +add_expanded_sid(const DOM_SID *sid, char **members, int *num_members) { - SAM_ACCOUNT *sam_account = NULL; + DOM_SID dom_sid; + uint32 rid; + struct winbindd_domain *domain; + int i; + + char *name = NULL; + enum SID_NAME_USE type; + + uint32 num_names; + DOM_SID **sid_mem; + char **names; + uint32 *types; + NTSTATUS result; - uint32 i; - DEBUG(3,("pdb: query_user_list\n")); + TALLOC_CTX *mem_ctx = talloc_init("add_expanded_sid"); - if (NT_STATUS_IS_ERR(result = pdb_init_sam(&sam_account))) { - return result; + if (mem_ctx == NULL) { + DEBUG(1, ("talloc_init failed\n")); + return; } - i = 0; - *info = NULL; - - if (pdb_setsampwent(False)) { - - while (pdb_getsampwent(sam_account)) { - - /* we return only nua accounts, or we will have duplicates */ - if (!idmap_check_sid_is_in_free_range(pdb_get_user_sid(sam_account))) { - continue; - } - - *info = talloc_realloc(mem_ctx, *info, (i + 1) * sizeof(WINBIND_USERINFO)); - if (!(*info)) { - DEBUG(0,("query_user_list: out of memory!\n")); - result = NT_STATUS_NO_MEMORY; - break; - } - - (*info)[i].user_sid = talloc(mem_ctx, sizeof(DOM_SID)); - (*info)[i].group_sid = talloc(mem_ctx, sizeof(DOM_SID)); - if (!((*info)[i].user_sid) || !((*info)[i].group_sid)) { - DEBUG(0,("query_user_list: out of memory!\n")); - result = NT_STATUS_NO_MEMORY; - break; - } - sid_copy((*info)[i].user_sid, pdb_get_user_sid(sam_account)); - sid_copy((*info)[i].group_sid, pdb_get_group_sid(sam_account)); - - (*info)[i].acct_name = talloc_strdup(mem_ctx, pdb_get_username(sam_account)); - (*info)[i].full_name = talloc_strdup(mem_ctx, pdb_get_fullname(sam_account)); - if (!((*info)[i].acct_name) || !((*info)[i].full_name)) { - DEBUG(0,("query_user_list: out of memory!\n")); - result = NT_STATUS_NO_MEMORY; - break; - } - - i++; - - if (NT_STATUS_IS_ERR(pdb_reset_sam(sam_account))) { - result = NT_STATUS_UNSUCCESSFUL; - break; - } + sid_copy(&dom_sid, sid); + sid_split_rid(&dom_sid, &rid); + + domain = find_domain_from_sid(&dom_sid); + + if (domain == NULL) { + DEBUG(3, ("Could not find domain for sid %s\n", + sid_string_static(sid))); + goto done; + } + + result = domain->methods->sid_to_name(domain, mem_ctx, sid, + &name, &type); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3, ("sid_to_name failed for sid %s\n", + sid_string_static(sid))); + goto done; + } + + DEBUG(10, ("Found name %s, type %d\n", name, type)); + + if (type == SID_NAME_USER) { + add_member(domain->name, name, members, num_members); + goto done; + } + + if (type != SID_NAME_DOM_GRP) { + DEBUG(10, ("Alias member %s neither user nor group, ignore\n", + name)); + goto done; + } + + /* Expand the domain group */ + + result = domain->methods->lookup_groupmem(domain, mem_ctx, + sid, &num_names, + &sid_mem, &names, + &types); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10, ("Could not lookup group members for %s: %s\n", + name, nt_errstr(result))); + goto done; + } + + for (i=0; iname, names[i], members, num_members); } - pdb_free_sam(&sam_account); - return result; + done: + talloc_destroy(mem_ctx); + return; +} + +BOOL fill_passdb_alias_grmem(struct winbindd_domain *domain, + DOM_SID *group_sid, + int *num_gr_mem, char **gr_mem, int *gr_mem_len) +{ + DOM_SID *members; + int i, num_members; + + *num_gr_mem = 0; + *gr_mem = NULL; + *gr_mem_len = 0; + + if (!pdb_enum_aliasmem(group_sid, &members, &num_members)) + return True; + + for (i=0; isid, 0, 1000000000, + num_entries, info)) { + /* Nothing to report, just exit. */ + return NT_STATUS_OK; + } - return result; + talloced_info = (struct acct_info *) + talloc_memdup(mem_ctx, *info, + *num_entries * sizeof(struct acct_info)); + + SAFE_FREE(*info); + *info = talloced_info; + + return NT_STATUS_OK; } /* convert a single name to a sid in a domain */ @@ -141,23 +225,13 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, DOM_SID *sid, enum SID_NAME_USE *type) { - SAM_ACCOUNT *sam_account = NULL; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - DEBUG(3,("pdb: name_to_sid name=%s (group support not implemented)\n", name)); - - if (NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) { - if (!pdb_getsampwnam(sam_account, name)) { - result = NT_STATUS_UNSUCCESSFUL; - } else { /* it is a sam user */ - sid_copy(sid, pdb_get_user_sid(sam_account)); - *type = SID_NAME_USER; - result = NT_STATUS_OK; - } - } + DEBUG(10, ("Finding name %s\n", name)); - pdb_free_sam(&sam_account); - return result; + if (!pdb_find_alias(name, sid)) + return NT_STATUS_NONE_MAPPED; + + *type = SID_NAME_ALIAS; + return NT_STATUS_OK; } /* @@ -165,141 +239,56 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, */ static NTSTATUS sid_to_name(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *sid, + const DOM_SID *sid, char **name, enum SID_NAME_USE *type) { - SAM_ACCOUNT *sam_account = NULL; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 id; + struct acct_info info; - DEBUG(3,("pdb: sid_to_name sid=%s\n", sid_string_static(sid))); + DEBUG(10, ("Converting SID %s\n", sid_string_static(sid))); - if (NT_STATUS_IS_OK(sid_to_uid(sid, &id))) { /* this is a user */ + if (!pdb_get_aliasinfo(sid, &info)) + return NT_STATUS_NONE_MAPPED; - if (NT_STATUS_IS_ERR(result = pdb_init_sam(&sam_account))) { - return result; - } - - if (!pdb_getsampwsid(sam_account, sid)) { - pdb_free_sam(&sam_account); - return NT_STATUS_UNSUCCESSFUL; - } - - *name = talloc_strdup(mem_ctx, pdb_get_username(sam_account)); - if (!(*name)) { - DEBUG(0,("query_user: out of memory!\n")); - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } + *name = talloc_strdup(mem_ctx, info.acct_name); + *type = SID_NAME_ALIAS; - pdb_free_sam(&sam_account); - *type = SID_NAME_USER; - result = NT_STATUS_OK; - - } else if (NT_STATUS_IS_OK(sid_to_gid(sid, &id))) { /* this is a group */ - - DEBUG(3,("pdb: sid_to_name: group support not implemented\n")); - result = NT_STATUS_UNSUCCESSFUL; - } - - return result; + return NT_STATUS_OK; } /* Lookup user information from a rid or username. */ static NTSTATUS query_user(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *user_sid, + const DOM_SID *user_sid, WINBIND_USERINFO *user_info) { - SAM_ACCOUNT *sam_account = NULL; - NTSTATUS result; - - DEBUG(3,("pdb: query_user sid=%s\n", sid_string_static(user_sid))); - - if (NT_STATUS_IS_ERR(result = pdb_init_sam(&sam_account))) { - return result; - } - - if (!pdb_getsampwsid(sam_account, user_sid)) { - pdb_free_sam(&sam_account); - return NT_STATUS_UNSUCCESSFUL; - } - - /* we return only nua accounts, or we will have duplicates */ - if (!idmap_check_sid_is_in_free_range(user_sid)) { - pdb_free_sam(&sam_account); - return NT_STATUS_UNSUCCESSFUL; - } - - user_info->user_sid = talloc(mem_ctx, sizeof(DOM_SID)); - user_info->group_sid = talloc(mem_ctx, sizeof(DOM_SID)); - if (!(user_info->user_sid) || !(user_info->group_sid)) { - DEBUG(0,("query_user: out of memory!\n")); - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } - sid_copy(user_info->user_sid, pdb_get_user_sid(sam_account)); - sid_copy(user_info->group_sid, pdb_get_group_sid(sam_account)); - - user_info->acct_name = talloc_strdup(mem_ctx, pdb_get_username(sam_account)); - user_info->full_name = talloc_strdup(mem_ctx, pdb_get_fullname(sam_account)); - if (!(user_info->acct_name) || !(user_info->full_name)) { - DEBUG(0,("query_user: out of memory!\n")); - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } - - pdb_free_sam(&sam_account); - return NT_STATUS_OK; -} + return NT_STATUS_NO_SUCH_USER; +} /* Lookup groups a user is a member of. I wish Unix had a call like this! */ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *user_sid, + const DOM_SID *user_sid, uint32 *num_groups, DOM_SID ***user_gids) { - NTSTATUS result = NT_STATUS_OK; - - DEBUG(3,("pdb: lookup_usergroups (group support not implemented)\n")); - - num_groups = 0; - user_gids = 0; - - return result; + return NT_STATUS_NO_SUCH_USER; } /* Lookup group membership given a rid. */ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - DOM_SID *group_sid, uint32 *num_names, + const DOM_SID *group_sid, uint32 *num_names, DOM_SID ***sid_mem, char ***names, uint32 **name_types) { - NTSTATUS result = NT_STATUS_NOT_IMPLEMENTED; - - DEBUG(3,("pdb: lookup_groupmem (group support not implemented)\n")); - - num_names = 0; - sid_mem = 0; - names = 0; - name_types = 0; - - return result; + return NT_STATUS_OK; } /* find the sequence number for a domain */ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) { - /* FIXME: we fake up the seq_num untill our passdb support it */ - static uint32 seq_num; - - DEBUG(3,("pdb: sequence_number\n")); - - *seq = seq_num++; - + *seq = 1; return NT_STATUS_OK; } @@ -311,24 +300,14 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, char ***alt_names, DOM_SID **dom_sids) { - NTSTATUS result = NT_STATUS_NOT_IMPLEMENTED; - - DEBUG(3,("pdb: trusted_domains (todo!)\n")); - - return result; + return NT_STATUS_OK; } /* find the domain sid for a domain */ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid) { - DEBUG(3,("pdb: domain_sid\n")); - - if (strcmp(domain->name, lp_workgroup())) { - return NT_STATUS_INVALID_PARAMETER; - } else { - sid_copy(sid, get_global_sam_sid()); - return NT_STATUS_OK; - } + sid_copy(sid, &domain->sid); + return NT_STATUS_OK; } /* find alternate names list for the domain diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index 9fbf47046d..8ff6cfd271 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -30,10 +30,8 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state) { - extern DOM_SID global_sid_Builtin; enum SID_NAME_USE type; - DOM_SID sid, tmp_sid; - uint32 rid; + DOM_SID sid; fstring name; fstring dom_name; @@ -50,15 +48,6 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - /* Don't look up BUILTIN sids */ - - sid_copy(&tmp_sid, &sid); - sid_split_rid(&tmp_sid, &rid); - - if (sid_equal(&tmp_sid, &global_sid_Builtin)) { - return WINBINDD_ERROR; - } - /* Lookup the sid */ if (!winbindd_lookup_name_by_sid(&sid, dom_name, name, &type)) { diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 403ba399c8..6ac5c48285 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -150,8 +150,9 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const } /* set flags about native_mode, active_directory */ - - set_dc_type_and_flags( domain ); + + if (!domain->internal) + set_dc_type_and_flags( domain ); DEBUG(3,("add_trusted_domain: %s is an %s %s domain\n", domain->name, domain->active_directory ? "ADS" : "NT4", @@ -303,6 +304,24 @@ BOOL init_domain_list(void) /* do an initial scan for trusted domains */ add_trusted_domains(domain); + + /* Add our local SAM domains */ + { + DOM_SID sid; + extern struct winbindd_methods passdb_methods; + struct winbindd_domain *dom; + + string_to_sid(&sid, "S-1-5-32"); + + dom = add_trusted_domain("BUILTIN", NULL, &passdb_methods, + &sid); + dom->internal = True; + + dom = add_trusted_domain(get_global_sam_name(), NULL, + &passdb_methods, + get_global_sam_sid()); + dom->internal = True; + } /* avoid rescanning this right away */ last_trustdom_scan = time(NULL); -- cgit From 26640ed9b1e512d8f7c04501eca8ae05635798b8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Mar 2004 17:38:07 +0000 Subject: Rest of my winbindd_passdb alias support (This used to be commit d1f38cd73ed5d71ec32e52bee8a60d206fea38ae) --- source3/Makefile.in | 1 + source3/lib/util_str.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/source3/Makefile.in b/source3/Makefile.in index f00cf0c172..81644744df 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -635,6 +635,7 @@ WINBINDD_OBJ1 = \ nsswitch/winbindd_wins.o \ nsswitch/winbindd_rpc.o \ nsswitch/winbindd_ads.o \ + nsswitch/winbindd_passdb.o \ nsswitch/winbindd_dual.o \ nsswitch/winbindd_acct.o diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 2be8b7eb64..be1e2ffeb1 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -2027,3 +2027,21 @@ SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr) return val; } + +void string_append(char **left, const char *right) +{ + int new_len = strlen(right) + 1; + + if (*left == NULL) { + *left = malloc(new_len); + *left[0] = '\0'; + } else { + new_len += strlen(*left); + *left = Realloc(*left, new_len); + } + + if (*left == NULL) + return; + + safe_strcat(*left, right, new_len-1); +} -- cgit From 66445d3de4d815c11734944bd9d2af795cdffb81 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Mar 2004 17:57:24 +0000 Subject: Make alias membership maintainable via net rpc group add/delmem. Alias creation and deletion still has to be done as well as a 'net alias' command. Volker (This used to be commit 975c60b997ac32610c5fa80a488e896596fa9917) --- source3/rpc_server/srv_lsa_nt.c | 5 + source3/rpc_server/srv_samr_nt.c | 254 +++++++++------------------------------ 2 files changed, 60 insertions(+), 199 deletions(-) diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 2d297d22f4..95cf188d67 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -165,6 +165,11 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2, status = lookup_name(dom_name, user, &sid, &name_type); + if (name_type == SID_NAME_WKN_GRP) { + /* BUILTIN aliases are still aliases :-) */ + name_type = SID_NAME_ALIAS; + } + DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" : "not found")); diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 42d19271e1..8861ce84c2 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -880,7 +880,7 @@ static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNIST Get the group entries - similar to get_sampwd_entries(). ******************************************************************/ -static NTSTATUS get_group_entries( enum SID_NAME_USE type, TALLOC_CTX *ctx, +static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx, uint32 *p_num_entries, uint32 max_entries ) { @@ -895,7 +895,8 @@ static NTSTATUS get_group_entries( enum SID_NAME_USE type, TALLOC_CTX *ctx, needed for some passdb backends to enumerate groups */ become_root(); - pdb_enum_group_mapping(type, &map, (int *)&group_entries, ENUM_ONLY_MAPPED); + pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, + ENUM_ONLY_MAPPED); unbecome_root(); num_entries=group_entries-start_idx; @@ -916,51 +917,54 @@ static NTSTATUS get_group_entries( enum SID_NAME_USE type, TALLOC_CTX *ctx, fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name); fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment); sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid); - (*d_grp)[i].attr=type; + (*d_grp)[i].attr=SID_NAME_DOM_GRP; } SAFE_FREE(map); *p_num_entries = num_entries; - DEBUG(10,("get_group_entries: returning %d entries\n", *p_num_entries)); + DEBUG(10,("get_group_domain_entries: returning %d entries\n", + *p_num_entries)); return NT_STATUS_OK; } /******************************************************************* - Wrapper for enuemrating domain groups + Wrapper for enumerating local groups ******************************************************************/ -static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, - DOM_SID *sid, uint32 start_idx, - uint32 *p_num_entries, uint32 max_entries ) +static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, + const DOM_SID *sid, uint32 start_idx, + uint32 *p_num_entries, uint32 max_entries ) { - return get_group_entries( SID_NAME_DOM_GRP, ctx, d_grp, sid, start_idx, - p_num_entries, max_entries ); -} + struct acct_info *info; + int i; + BOOL res; -/******************************************************************* - Wrapper for enumerating local groups - ******************************************************************/ + become_root(); + res = pdb_enum_aliases(sid, start_idx, max_entries, + p_num_entries, &info); + unbecome_root(); -static NTSTATUS get_group_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, - DOM_SID *sid, uint32 start_idx, - uint32 *p_num_entries, uint32 max_entries) -{ - if ( sid_equal(sid, &global_sid_Builtin) ) { - return get_group_entries( SID_NAME_WKN_GRP, ctx, d_grp, - sid, start_idx, p_num_entries, max_entries ); - } - else if ( sid_equal(sid, get_global_sam_sid()) ) { - return get_group_entries( SID_NAME_ALIAS, ctx, d_grp, - sid, start_idx, p_num_entries, max_entries ); + if (!res) + return NT_STATUS_ACCESS_DENIED; + + *d_grp = talloc(ctx, sizeof(DOMAIN_GRP) * (*p_num_entries)); + + if (*d_grp == NULL) { + SAFE_FREE(info); + return NT_STATUS_NO_MEMORY; } - /* can't do anything with this SID */ - - *p_num_entries = 0; + for (i=0; i<*p_num_entries; i++) { + fstrcpy((*d_grp)[i].name, info[i].acct_name); + fstrcpy((*d_grp)[i].comment, info[i].acct_desc); + (*d_grp)[i].rid = info[i].rid; + (*d_grp)[i].attr = SID_NAME_ALIAS; + } + SAFE_FREE(info); return NT_STATUS_OK; } @@ -1026,8 +1030,8 @@ NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, S sid_to_string(sid_str, &sid); DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str)); - status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, - &num_entries, MAX_SAM_ENTRIES); + status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, + &num_entries, MAX_SAM_ENTRIES); if (NT_STATUS_IS_ERR(status)) return status; make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp); @@ -1245,7 +1249,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u) { DOM_SID sid; - GROUP_MAP map; + struct acct_info info; uint32 acc_granted; BOOL ret; @@ -1260,12 +1264,8 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM return r_u->status; } - if (!sid_check_is_in_our_domain(&sid) && - !sid_check_is_in_builtin(&sid)) - return NT_STATUS_OBJECT_TYPE_MISMATCH; - become_root(); - ret = pdb_getgrsid(&map, sid); + ret = pdb_get_aliasinfo(&sid, &info); unbecome_root(); if ( !ret ) @@ -1275,12 +1275,13 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM case 1: r_u->ptr = 1; r_u->ctr.switch_value1 = 1; - init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment); + init_samr_alias_info1(&r_u->ctr.alias.info1, + info.acct_name, 1, info.acct_desc); break; case 3: r_u->ptr = 1; r_u->ctr.switch_value1 = 3; - init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment); + init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc); break; default: return NT_STATUS_INVALID_INFO_CLASS; @@ -3223,15 +3224,11 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ { int i; - GROUP_MAP map; int num_sids = 0; DOM_SID2 *sid; DOM_SID *sids=NULL; DOM_SID alias_sid; - DOM_SID als_sid; - uint32 alias_rid; - fstring alias_sid_str; uint32 acc_granted; @@ -3243,35 +3240,12 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) { return r_u->status; } - - sid_copy(&als_sid, &alias_sid); - sid_to_string(alias_sid_str, &alias_sid); - sid_split_rid(&alias_sid, &alias_rid); - DEBUG(10, ("sid is %s\n", alias_sid_str)); + DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid))); - if (sid_equal(&alias_sid, &global_sid_Builtin)) { - DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n")); - if(!get_builtin_group_from_sid(&als_sid, &map)) - return NT_STATUS_NO_SUCH_ALIAS; - } else { - if (sid_equal(&alias_sid, get_global_sam_sid())) { - DEBUG(10, ("lookup on Server SID\n")); - if(!get_local_group_from_sid(&als_sid, &map)) { - fstring alias_sid_string; - DEBUG(10, ("Alias %s not found\n", sid_to_string(alias_sid_string, &als_sid))); - return NT_STATUS_NO_SUCH_ALIAS; - } - } - } - - if (!get_sid_list_of_group(map.gid, &sids, &num_sids)) { - fstring alias_sid_string; - DEBUG(10, ("Alias %s found, but member list unavailable\n", sid_to_string(alias_sid_string, &als_sid))); + if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids)) return NT_STATUS_NO_SUCH_ALIAS; - } - DEBUG(10, ("sid is %s\n", alias_sid_str)); sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_sids); if (num_sids!=0 && sid == NULL) { SAFE_FREE(sids); @@ -3282,7 +3256,6 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ init_dom_sid2(&sid[i], &sids[i]); } - DEBUG(10, ("sid is %s\n", alias_sid_str)); init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK); SAFE_FREE(sids); @@ -3368,15 +3341,6 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u) { DOM_SID alias_sid; - fstring alias_sid_str; - uid_t uid; - struct passwd *pwd; - struct group *grp; - fstring grp_name; - GROUP_MAP map; - NTSTATUS ret; - SAM_ACCOUNT *sam_user = NULL; - BOOL check; uint32 acc_granted; /* Find the policy handle. Open a policy on it. */ @@ -3387,75 +3351,11 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD return r_u->status; } - sid_to_string(alias_sid_str, &alias_sid); - DEBUG(10, ("sid is %s\n", alias_sid_str)); - - if (sid_compare(&alias_sid, get_global_sam_sid())>0) { - DEBUG(10, ("adding member on Server SID\n")); - if(!get_local_group_from_sid(&alias_sid, &map)) - return NT_STATUS_NO_SUCH_ALIAS; - - } else { - if (sid_compare(&alias_sid, &global_sid_Builtin)>0) { - DEBUG(10, ("adding member on BUILTIN SID\n")); - if( !get_builtin_group_from_sid(&alias_sid, &map)) - return NT_STATUS_NO_SUCH_ALIAS; - - } else - return NT_STATUS_NO_SUCH_ALIAS; - } - - ret = pdb_init_sam(&sam_user); - if (!NT_STATUS_IS_OK(ret)) - return ret; - - check = pdb_getsampwsid(sam_user, &q_u->sid.sid); - - if (check != True) { - pdb_free_sam(&sam_user); - return pdb_add_aliasmem(&alias_sid, &q_u->sid.sid) ? - NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; - } - - /* check a real user exist before we run the script to add a user to a group */ - if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) { - pdb_free_sam(&sam_user); - return NT_STATUS_NO_SUCH_USER; - } - - pdb_free_sam(&sam_user); - - if ((pwd=getpwuid_alloc(uid)) == NULL) { - return NT_STATUS_NO_SUCH_USER; - } - - if ((grp=getgrgid(map.gid)) == NULL) { - passwd_free(&pwd); - return NT_STATUS_NO_SUCH_ALIAS; - } - - /* we need to copy the name otherwise it's overloaded in user_in_group_list */ - fstrcpy(grp_name, grp->gr_name); - - /* if the user is already in the group */ - if(user_in_unix_group_list(pwd->pw_name, grp_name)) { - passwd_free(&pwd); - return NT_STATUS_MEMBER_IN_ALIAS; - } - - /* - * ok, the group exist, the user exist, the user is not in the group, - * we can (finally) add it to the group ! - */ - smb_add_user_group(grp_name, pwd->pw_name); + DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid))); - /* check if the user has been added then ... */ - if(!user_in_unix_group_list(pwd->pw_name, grp_name)) { - passwd_free(&pwd); - return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */ - } + if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid)) + return NT_STATUS_ACCESS_DENIED; - passwd_free(&pwd); return NT_STATUS_OK; } @@ -3466,11 +3366,6 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u) { DOM_SID alias_sid; - fstring alias_sid_str; - struct group *grp; - fstring grp_name; - GROUP_MAP map; - SAM_ACCOUNT *sam_pass=NULL; uint32 acc_granted; /* Find the policy handle. Open a policy on it. */ @@ -3481,49 +3376,12 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE return r_u->status; } - sid_to_string(alias_sid_str, &alias_sid); - DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str)); + DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", + sid_string_static(&alias_sid))); - if (!sid_check_is_in_our_domain(&alias_sid) && - !sid_check_is_in_builtin(&alias_sid)) { - DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n")); - return NT_STATUS_NO_SUCH_ALIAS; - } - - if( !get_local_group_from_sid(&alias_sid, &map) && - !get_builtin_group_from_sid(&alias_sid, &map) ) - return NT_STATUS_NO_SUCH_ALIAS; - - if ((grp=getgrgid(map.gid)) == NULL) - return NT_STATUS_NO_SUCH_ALIAS; - - /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */ - fstrcpy(grp_name, grp->gr_name); - - /* check if the user exists before trying to remove it from the group */ - pdb_init_sam(&sam_pass); - if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) { - DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass))); - pdb_free_sam(&sam_pass); - return pdb_del_aliasmem(&alias_sid, &q_u->sid.sid) ? - NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; - } - - /* if the user is not in the group */ - if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) { - pdb_free_sam(&sam_pass); - return NT_STATUS_MEMBER_NOT_IN_ALIAS; - } - - smb_delete_user_group(grp_name, pdb_get_username(sam_pass)); - - /* check if the user has been removed then ... */ - if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) { - pdb_free_sam(&sam_pass); - return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */ - } - - pdb_free_sam(&sam_pass); + if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid)) + return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_OK; } @@ -4140,7 +3998,7 @@ NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u) { DOM_SID group_sid; - GROUP_MAP map; + struct acct_info info; ALIAS_INFO_CTR *ctr; uint32 acc_granted; @@ -4151,22 +4009,20 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_ return r_u->status; } - if (!get_local_group_from_sid(&group_sid, &map) && - !get_builtin_group_from_sid(&group_sid, &map)) - return NT_STATUS_NO_SUCH_GROUP; - ctr=&q_u->ctr; switch (ctr->switch_value1) { case 3: - unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1); + unistr2_to_ascii(info.acct_desc, + &(ctr->alias.info3.uni_acct_desc), + sizeof(info.acct_desc)-1); break; default: return NT_STATUS_INVALID_INFO_CLASS; } - if(!pdb_update_group_mapping_entry(&map)) { - return NT_STATUS_NO_SUCH_GROUP; + if(!pdb_set_aliasinfo(&group_sid, &info)) { + return NT_STATUS_ACCESS_DENIED; } return NT_STATUS_OK; -- cgit From badb5b4e16c2987f19a950edf363f26555224e75 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 14 Mar 2004 03:47:55 +0000 Subject: Merge from 3.0 (This used to be commit c8db2f7cdbe280ad3c3d35c0640d19b0f664bd36) --- source3/utils/net_ads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 24ae9a8811..6eec71aedf 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -147,7 +147,7 @@ static ADS_STRUCT *ads_startup(void) retry: if (!opt_password && need_password && !opt_machine_pass) { char *prompt; - asprintf(&prompt,"%s password: ", opt_user_name); + asprintf(&prompt,"%s's password: ", opt_user_name); opt_password = getpass(prompt); free(prompt); } -- cgit From af6225afa95cf1d8dd6bb1bfb438daaf6097e30a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 14 Mar 2004 07:16:05 +0000 Subject: When trying to remove a user from a group, winbind should be informed about the user and group... Volker (This used to be commit 87fa7904f7da5f4a80ca465c09ae4ad274e81690) --- source3/nsswitch/wb_client.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c index 0c6644e9d0..90e4584dab 100644 --- a/source3/nsswitch/wb_client.c +++ b/source3/nsswitch/wb_client.c @@ -499,6 +499,9 @@ BOOL winbind_remove_user_from_group( const char *user, const char *group ) ZERO_STRUCT(response); + fstrcpy( request.data.acct_mgt.username, user ); + fstrcpy( request.data.acct_mgt.groupname, group ); + result = winbindd_request( WINBINDD_REMOVE_USER_FROM_GROUP, &request, &response); return result == NSS_STATUS_SUCCESS; -- cgit From 5b0f30e01c5a51f98025b035bfa5e00eb0268fef Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 14 Mar 2004 10:24:19 +0000 Subject: Add and delete aliases via srv_samr_nt. For that I added a RID allocation call to winbindd. idmap_allocate_rid wants information about whether this will be a user or a group, I did not export this to the winbind interface. The reason for idmap to get that info is to keep consistent with the algorithmic convention to alloc only even rids for users and odd rids for groups. I'm not fully convinced that this really gains us anything. Any real good arguments? Volker (This used to be commit 7f62cf933cad69799204bfdc773e08ff0dde0b20) --- source3/groupdb/mapping.c | 42 ++++++++++++++++++++++++---- source3/nsswitch/wb_client.c | 28 ++++++++++++++++--- source3/nsswitch/wbinfo.c | 19 +++++++++++++ source3/nsswitch/winbindd.c | 1 + source3/nsswitch/winbindd_nss.h | 5 ++-- source3/nsswitch/winbindd_sid.c | 20 ++++++++++++++ source3/rpc_server/srv_samr_nt.c | 59 ++++++++-------------------------------- 7 files changed, 116 insertions(+), 58 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 818a4acb84..cbf022f377 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -362,7 +362,7 @@ static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map) Remove a group mapping entry. ****************************************************************************/ -static BOOL group_map_remove(DOM_SID sid) +static BOOL group_map_remove(const DOM_SID *sid) { TDB_DATA kbuf, dbuf; pstring key; @@ -375,7 +375,7 @@ static BOOL group_map_remove(DOM_SID sid) /* the key is the SID, retrieving is direct */ - sid_to_string(string_sid, &sid); + sid_to_string(string_sid, sid); slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid); kbuf.dptr = key; @@ -1266,7 +1266,7 @@ NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods, NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods, DOM_SID sid) { - return group_map_remove(sid) ? + return group_map_remove(&sid) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } @@ -1289,13 +1289,45 @@ NTSTATUS pdb_default_find_alias(struct pdb_methods *methods, NTSTATUS pdb_default_create_alias(struct pdb_methods *methods, const char *name, uint32 *rid) { - return NT_STATUS_ACCESS_DENIED; + DOM_SID sid; + enum SID_NAME_USE type; + uint32 new_rid; + gid_t gid; + + if (lookup_name(get_global_sam_name(), name, &sid, &type)) + return NT_STATUS_ALIAS_EXISTS; + + if (!winbind_allocate_rid(&new_rid)) + return NT_STATUS_ACCESS_DENIED; + + sid_copy(&sid, get_global_sam_sid()); + sid_append_rid(&sid, new_rid); + + /* Here we allocate the gid */ + if (!winbind_sid_to_gid(&gid, &sid)) { + DEBUG(0, ("Could not get gid for new RID\n")); + return NT_STATUS_ACCESS_DENIED; + } + + if (!add_initial_entry(gid, sid_string_static(&sid), SID_NAME_ALIAS, + name, "")) { + DEBUG(0, ("Could not add group mapping entry for alias %s\n", + name)); + return NT_STATUS_ACCESS_DENIED; + } + + *rid = new_rid; + + return NT_STATUS_OK; } NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods, const DOM_SID *sid) { - return NT_STATUS_ACCESS_DENIED; + if (!group_map_remove(sid)) + return NT_STATUS_ACCESS_DENIED; + + return NT_STATUS_OK; } NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods, diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c index 90e4584dab..32dfc8deca 100644 --- a/source3/nsswitch/wb_client.c +++ b/source3/nsswitch/wb_client.c @@ -235,6 +235,30 @@ BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) return (result == NSS_STATUS_SUCCESS); } +BOOL winbind_allocate_rid(uint32 *rid) +{ + struct winbindd_request request; + struct winbindd_response response; + int result; + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + /* Make request */ + + result = winbindd_request(WINBINDD_ALLOCATE_RID, &request, &response); + + if (result != NSS_STATUS_SUCCESS) + return False; + + /* Copy out result */ + *rid = response.data.rid; + + return True; +} + /* Fetch the list of groups a user is a member of from winbindd. This is used by winbind_getgroups. */ @@ -595,8 +619,6 @@ BOOL winbind_delete_group( const char *group ) } /***********************************************************************/ -#if 0 /* not needed currently since winbindd_acct was added -- jerry */ - /* Call winbindd to convert SID to uid. Do not allocate */ BOOL winbind_sid_to_uid_query(uid_t *puid, const DOM_SID *sid) @@ -667,7 +689,5 @@ BOOL winbind_sid_to_gid_query(gid_t *pgid, const DOM_SID *sid) return (result == NSS_STATUS_SUCCESS); } -#endif /* JERRY */ - /***********************************************************************/ diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 772332ee59..af2a0ce7c6 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -436,6 +436,18 @@ static BOOL wbinfo_sid_to_gid(char *sid) return True; } +static BOOL wbinfo_allocate_rid(void) +{ + uint32 rid; + + if (!winbind_allocate_rid(&rid)) + return False; + + d_printf("New rid: %d\n", rid); + + return True; +} + /* Convert sid to string */ static BOOL wbinfo_lookupsid(char *sid) @@ -983,6 +995,7 @@ int main(int argc, char **argv) { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" }, { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" }, { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid", "SID" }, + { "allocate-rid", 'A', POPT_ARG_NONE, 0, 'A', "Get a new RID out of idmap" }, { "create-user", 'c', POPT_ARG_STRING, &string_arg, 'c', "Create a local user account", "name" }, { "delete-user", 'x', POPT_ARG_STRING, &string_arg, 'x', "Delete a local user account", "name" }, { "create-group", 'C', POPT_ARG_STRING, &string_arg, 'C', "Create a local group", "name" }, @@ -1102,6 +1115,12 @@ int main(int argc, char **argv) goto done; } break; + case 'A': + if (!wbinfo_allocate_rid()) { + d_printf("Could not allocate a RID\n"); + goto done; + } + break; case 't': if (!wbinfo_check_secret()) { d_printf("Could not check secret\n"); diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 8a0d0f7573..c4319d493a 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -255,6 +255,7 @@ static struct dispatch_table dispatch_table[] = { { WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" }, { WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" }, { WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" }, + { WINBINDD_ALLOCATE_RID, winbindd_allocate_rid, "ALLOCATE_RID" }, /* Miscellaneous */ diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index 0d110b8afa..745a29facc 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -36,7 +36,7 @@ /* Update this when you change the interface. */ -#define WINBIND_INTERFACE_VERSION 9 +#define WINBIND_INTERFACE_VERSION 10 /* Socket commands */ @@ -84,6 +84,7 @@ enum winbindd_cmd { WINBINDD_SID_TO_GID, WINBINDD_UID_TO_SID, WINBINDD_GID_TO_SID, + WINBINDD_ALLOCATE_RID, /* Miscellaneous other stuff */ @@ -266,7 +267,7 @@ struct winbindd_response { char nt_session_key[16]; char first_8_lm_hash[8]; } auth; - uint32 rid; /* create user or group */ + uint32 rid; /* create user or group or allocate rid */ struct { fstring name; fstring alt_name; diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index 8ff6cfd271..d4206558c5 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -434,3 +434,23 @@ done: return WINBINDD_OK; } + +enum winbindd_result winbindd_allocate_rid(struct winbindd_cli_state *state) +{ + if ( !state->privileged ) { + DEBUG(2, ("winbindd_allocate_rid: non-privileged access " + "denied!\n")); + return WINBINDD_ERROR; + } + + /* We tell idmap to always allocate a user RID. There might be a good + * reason to keep RID allocation for users to even and groups to + * odd. This needs discussion I think. For now only allocate user + * rids. */ + + if (!NT_STATUS_IS_OK(idmap_allocate_rid(&state->response.data.rid, + USER_RID_TYPE))) + return WINBINDD_ERROR; + + return WINBINDD_OK; +} diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 8861ce84c2..b1147e50ef 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3708,12 +3708,6 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u) { DOM_SID alias_sid; - DOM_SID dom_sid; - uint32 alias_rid; - fstring alias_sid_str; - gid_t gid; - struct group *grp; - GROUP_MAP map; uint32 acc_granted; DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__)); @@ -3725,38 +3719,18 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) { return r_u->status; } - - sid_copy(&dom_sid, &alias_sid); - sid_to_string(alias_sid_str, &dom_sid); - sid_split_rid(&dom_sid, &alias_rid); - DEBUG(10, ("sid is %s\n", alias_sid_str)); + DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid))); - /* we check if it's our SID before deleting */ - if (!sid_equal(&dom_sid, get_global_sam_sid())) + if (!sid_check_is_in_our_domain(&alias_sid)) return NT_STATUS_NO_SUCH_ALIAS; - + DEBUG(10, ("lookup on Local SID\n")); - if(!get_local_group_from_sid(&alias_sid, &map)) - return NT_STATUS_NO_SUCH_ALIAS; - - gid=map.gid; - - /* check if group really exists */ - if ( (grp=getgrgid(gid)) == NULL) - return NT_STATUS_NO_SUCH_ALIAS; - - /* we can delete the UNIX group */ - smb_delete_group(grp->gr_name); - - /* check if the group has been successfully deleted */ - if ( (grp=getgrgid(gid)) != NULL) + /* Have passdb delete the alias */ + if (!pdb_delete_alias(&alias_sid)) return NT_STATUS_ACCESS_DENIED; - /* don't check if we removed it as it could be an un-mapped group */ - pdb_delete_group_mapping_entry(alias_sid); - if (!close_policy_hnd(p, &q_u->alias_pol)) return NT_STATUS_OBJECT_NAME_INVALID; @@ -3834,7 +3808,6 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S DOM_SID dom_sid; DOM_SID info_sid; fstring name; - fstring sid_string; struct group *grp; struct samr_info *info; uint32 acc_granted; @@ -3855,26 +3828,18 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1); - /* check if group already exists */ - if ( (grp=getgrnam(name)) != NULL) - return NT_STATUS_ALIAS_EXISTS; - - /* we can create the UNIX group */ - if (smb_create_group(name, &gid) != 0) - return NT_STATUS_ACCESS_DENIED; - - /* check if the group has been successfully created */ - if ((grp=getgrgid(gid)) == NULL) + /* Have passdb create the alias */ + if (!pdb_create_alias(name, &r_u->rid)) return NT_STATUS_ACCESS_DENIED; - r_u->rid=pdb_gid_to_group_rid(grp->gr_gid); - sid_copy(&info_sid, get_global_sam_sid()); sid_append_rid(&info_sid, r_u->rid); - sid_to_string(sid_string, &info_sid); - /* add the group to the mapping table */ - if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL)) + if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid))) + return NT_STATUS_ACCESS_DENIED; + + /* check if the group has been successfully created */ + if ((grp=getgrgid(gid)) == NULL) return NT_STATUS_ACCESS_DENIED; if ((info = get_samr_info_by_sid(&info_sid)) == NULL) -- cgit From 6cd06f816d8b5c77f7691ecae4aa2ea84b305cc0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 14 Mar 2004 10:28:21 +0000 Subject: Fix 'getent group aliasname', this did not look in pdb. (This used to be commit 3acac5d626b2897fd2c4b291dd4e0a6c9ceffcfe) --- source3/nsswitch/winbindd_group.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 94bd0fa0b9..be95e49ba4 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -250,14 +250,11 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) /* if no domain or our local domain, then do a local tdb search */ - if ( !*name_domain || strequal(name_domain, get_global_sam_name()) ) { + if ( (!*name_domain || strequal(name_domain, get_global_sam_name())) && + ((grp = wb_getgrnam(name_group)) != NULL) ) { + char *buffer = NULL; - if ( !(grp=wb_getgrnam(name_group)) ) { - DEBUG(5,("winbindd_getgrnam: lookup for %s\\%s failed\n", - name_domain, name_group)); - return WINBINDD_ERROR; - } memcpy( &state->response.data.gr, grp, sizeof(WINBINDD_GR) ); gr_mem_len = gr_mem_buffer( &buffer, grp->gr_mem, grp->num_gr_mem ); @@ -269,6 +266,13 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) return WINBINDD_OK; } + /* if no domain or our local domain and no local tdb group, default to + * our local domain for aliases */ + + if ( !*name_domain || strequal(name_domain, get_global_sam_name()) ) { + fstrcpy(name_domain, get_global_sam_name()); + } + /* Get info for the domain */ if ((domain = find_domain_from_name(name_domain)) == NULL) { @@ -294,7 +298,8 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) } if ( !((name_type==SID_NAME_DOM_GRP) || - ((name_type==SID_NAME_ALIAS) && domain->primary)) ) + ((name_type==SID_NAME_ALIAS) && domain->primary) || + ((name_type==SID_NAME_ALIAS) && domain->internal)) ) { DEBUG(1, ("name '%s' is not a local or domain group: %d\n", name_group, name_type)); -- cgit From 916d7852a57f9ef2f3c3b7e9a3dee0abce180737 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 14 Mar 2004 10:36:07 +0000 Subject: Clean up a bit :-) Volker (This used to be commit 66c4a6dee88274c2e1493224b0ba694418b32796) --- source3/groupdb/mapping.c | 13 ++++++++++ source3/passdb/util_sam_sid.c | 57 ------------------------------------------- 2 files changed, 13 insertions(+), 57 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index cbf022f377..319d39c99f 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -531,6 +531,19 @@ static NTSTATUS add_aliasmem(const DOM_SID *alias, const DOM_SID *member) return (result == 0 ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED); } +static void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num) +{ + *sids = Realloc(*sids, ((*num)+1) * sizeof(DOM_SID)); + + if (*sids == NULL) + return; + + sid_copy(&((*sids)[*num]), sid); + *num += 1; + + return; +} + static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, int *num) { GROUP_MAP map; diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c index 1d1e74cd6f..f6cc2491a8 100644 --- a/source3/passdb/util_sam_sid.c +++ b/source3/passdb/util_sam_sid.c @@ -305,60 +305,3 @@ BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char return False; } - -void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num) -{ - *sids = Realloc(*sids, ((*num)+1) * sizeof(DOM_SID)); - - if (*sids == NULL) - return; - - sid_copy(&((*sids)[*num]), sid); - *num += 1; - - return; -} - -void add_gid_to_array_unique(gid_t gid, gid_t **gids, int *num) -{ - int i; - - if ((*num) >= groups_max()) - return; - - for (i=0; i<*num; i++) { - if ((*gids)[i] == gid) - return; - } - - *gids = Realloc(*gids, (*num+1) * sizeof(gid_t)); - - if (*gids == NULL) - return; - - (*gids)[*num] = gid; - *num += 1; -} - -/************************************************************************** - Augment a gid list with gids from alias memberships -***************************************************************************/ - -void add_foreign_gids_from_sid(const DOM_SID *sid, gid_t **gids, int *num) -{ - DOM_SID *aliases; - int j, num_aliases; - - if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) - return; - - for (j=0; j Date: Sun, 14 Mar 2004 11:15:37 +0000 Subject: Ok, one of the latest cleanups did too much... :-) Re-add adding the local aliases to winbindd_getgroups. Volker (This used to be commit ae080f2cfaa50cf16c91d760f63db2c721e251c5) --- source3/nsswitch/winbindd_group.c | 91 ++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index be95e49ba4..74ede8621b 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -911,6 +911,53 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) return WINBINDD_OK; } +static void add_gid_to_array_unique(gid_t gid, gid_t **gids, int *num) +{ + int i; + + if ((*num) >= groups_max()) + return; + + for (i=0; i<*num; i++) { + if ((*gids)[i] == gid) + return; + } + + *gids = Realloc(*gids, (*num+1) * sizeof(gid_t)); + + if (*gids == NULL) + return; + + (*gids)[*num] = gid; + *num += 1; +} + +static void add_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num) +{ + gid_t gid; + DOM_SID *aliases; + int j, num_aliases; + + DEBUG(10, ("Adding gids from SID: %s\n", sid_string_static(sid))); + + if (NT_STATUS_IS_OK(idmap_sid_to_gid(sid, &gid, 0))) + add_gid_to_array_unique(gid, gids, num); + + /* Add nested group memberships */ + + if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) + return; + + for (j=0; jnum_groups2, info3->num_other_sids)); num_groups = info3->num_other_sids + info3->num_groups2; - gid_list = calloc(sizeof(gid_t), num_groups); /* Go through each other sid and convert it to a gid */ @@ -1019,23 +1067,11 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) continue; } - /* Map to a gid */ - - 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))); - continue; - } + add_gids_from_sid(&info3->other_sids[i].sid, + &gid_list, &num_gids); - /* We've jumped through a lot of hoops to get here */ - - DEBUG(10, ("winbindd_getgroups: mapped other sid %s to " - "gid %lu\n", sid_string_static( - &info3->other_sids[i].sid), - (unsigned long)gid_list[num_gids])); - - num_gids++; + if (gid_list == NULL) + goto done; } for (i = 0; i < info3->num_groups2; i++) { @@ -1045,12 +1081,10 @@ 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(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))); - } + add_gids_from_sid(&group_sid, &gid_list, &num_gids); - num_gids++; + if (gid_list == NULL) + goto done; } SAFE_FREE(info3); @@ -1068,12 +1102,11 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; for (i = 0; i < num_groups; i++) { - 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; - } - num_gids++; + add_gids_from_sid(user_grpsids[i], + &gid_list, &num_gids); + + if (gid_list == NULL) + goto done; } } -- cgit From 12fb2d73050a911c7a86749be3639b2c1da84059 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 15 Mar 2004 15:16:29 +0000 Subject: fix byte ordering problem when storing the updating pid for the lpq cache; was causing an abort in process_exists() on solaris (This used to be commit ce49e4f2b904ab64ea98af4736147795669495df) --- source3/printing/printing.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ad11108a5a..ed19c01f24 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -818,6 +818,8 @@ static void set_updating_pid(const fstring printer_name, BOOL delete) TDB_DATA key; TDB_DATA data; pid_t updating_pid = sys_getpid(); + uint8 buffer[4]; + struct tdb_print_db *pdb = get_print_db_byname(printer_name); if (!pdb) @@ -833,8 +835,9 @@ static void set_updating_pid(const fstring printer_name, BOOL delete) return; } - data.dptr = (void *)&updating_pid; - data.dsize = sizeof(pid_t); + SIVAL( buffer, 0, updating_pid); + data.dptr = (void *)buffer; + data.dsize = 4; /* we always assume this is a 4 byte value */ tdb_store(pdb->tdb, key, data, TDB_REPLACE); release_print_db(pdb); -- cgit From 11f6251b771e59020af02599ea419e7d7ff682de Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 15 Mar 2004 16:12:52 +0000 Subject: sync small fixes from 3.0 and fix compiler warning in priv code (This used to be commit c640594c9362dca625a8fa51b453dafe1f3e980d) --- source3/Makefile.in | 1 + source3/configure.in | 11 ++++------- source3/include/adt_tree.h | 2 +- source3/lib/adt_tree.c | 6 +++--- source3/lib/charcnv.c | 2 +- source3/passdb/pdb_tdb.c | 2 +- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 81644744df..324a70069e 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -69,6 +69,7 @@ CONFIGLIBDIR = $(LIBDIR)/config CONFIGDIR = @configdir@ VARDIR = @localstatedir@ MANDIR = @mandir@ +DATADIR = @datadir@ # The permissions to give the executables INSTALLPERMS = 0755 diff --git a/source3/configure.in b/source3/configure.in index 6cb64e8d87..3a15e9053b 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -27,19 +27,17 @@ AC_ARG_WITH(fhs, [ --with-fhs Use FHS-compliant paths (default=no)], [ case "$withval" in yes) - configdir="${sysconfdir}/samba" lockdir="\${VARDIR}/lib/samba" piddir="\${VARDIR}/run" mandir="\${prefix}/share/man" logfilebase="\${VARDIR}/log/samba" privatedir="\${CONFIGDIR}/private" libdir="\${prefix}/lib/samba" - swatdir="\${prefix}/share/samba/swat" + configdir="${sysconfdir}/samba" + swatdir="\${DATADIR}/samba/swat", ;; esac]) -lmhostsfile="\${CONFIGDIR}/lmhosts" - ################################################# # set private directory location AC_ARG_WITH(privatedir, @@ -929,8 +927,6 @@ AC_CHECK_FUNCS(syslog vsyslog timegm) AC_CHECK_FUNCS(setlocale nl_langinfo) # setbuffer, shmget, shm_open are needed for smbtorture AC_CHECK_FUNCS(setbuffer shmget shm_open backtrace_symbols) - -# IRIX stack backtrace AC_CHECK_HEADERS(libexc.h) AC_CHECK_LIB(exc, trace_back_stack) @@ -2960,7 +2956,7 @@ fi dictpath="/usr/lib/cracklib_dict" - +with_cracklib=yes ############################################### # test for where we get FaciestCheck from AC_MSG_CHECKING(where to use cracklib from (default=$dictpath)) @@ -3326,6 +3322,7 @@ AC_TRY_COMPILE([ #define NO_PROTO_H 1 #define NO_CONFIG_H 1 #define HAVE_SYS_QUOTAS 1 +#include "${srcdir-.}/${samba_cv_sysquotas_file}" #include "${srcdir-.}/lib/sysquotas.c" ],[],samba_cv_SYSQUOTA_WORKS=yes,samba_cv_SYSQUOTA_WORKS=no) CPPFLAGS="$SAVE_CPPFLAGS" diff --git a/source3/include/adt_tree.h b/source3/include/adt_tree.h index b1bf7ad85d..12e2ea5cc5 100644 --- a/source3/include/adt_tree.h +++ b/source3/include/adt_tree.h @@ -32,7 +32,7 @@ typedef struct _tree_node { typedef struct _tree_root { TREE_NODE *root; int (*compare)(void* x, void *y); - void (*free)(void *p); + void (*free_func)(void *p); } SORTED_TREE; #endif diff --git a/source3/lib/adt_tree.c b/source3/lib/adt_tree.c index 0bc224ec23..bd857e205a 100644 --- a/source3/lib/adt_tree.c +++ b/source3/lib/adt_tree.c @@ -65,7 +65,7 @@ SORTED_TREE* sorted_tree_init( void *data_p, ZERO_STRUCTP( tree ); tree->compare = cmp_fn; - tree->free = free_fn; + tree->free_func = free_fn; if ( !(tree->root = (TREE_NODE*)malloc( sizeof(TREE_NODE) )) ) { SAFE_FREE( tree ); @@ -110,8 +110,8 @@ void sorted_tree_destroy( SORTED_TREE *tree ) if ( tree->root ) sorted_tree_destroy_children( tree->root ); - if ( tree->free ) - tree->free( tree->root ); + if ( tree->free_func ) + tree->free_func( tree->root ); SAFE_FREE( tree ); } diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index c2213c966d..20af806d90 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -1110,7 +1110,7 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_ if (ucs2_align(base_ptr, src, flags)) { src = (const void *)((const char *)src + 1); - if (src_len > 0) + if (src_len != (size_t)-1) src_len--; } diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index aef088c124..8f2fe7651f 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -1204,7 +1204,7 @@ static int tdbsam_traverse_privilege(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data int len; s = data.dptr; - while (c = strchr(s, ',')) { + while ((c=strchr(s, ',')) !=NULL) { len = MAX((c - s), strlen(pt->sid_list[i])); if (strncmp(s, pt->sid_list[i], len) == 0) { DEBUG(10, ("sid [%s] found in users sid list\n", pt->sid_list[i])); -- cgit From 1054f6b10726a2e1c316df4427d8547d6b9e2ce8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 15 Mar 2004 16:17:51 +0000 Subject: more fixes from 3.0 (This used to be commit 211cead67ca2c8c017ee5eec1d6989d4928236bf) --- source3/Makefile.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 324a70069e..def96051b7 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1256,6 +1256,8 @@ installbin: all installdirs @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(DESTDIR) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(BIN_PROGS) +# Some symlinks are required for the 'probing' of modules. +# This mechanism should go at some point.. installmodules: modules installdirs @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(VFSLIBDIR) $(VFS_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(PDBLIBDIR) $(PDB_MODULES) @@ -1263,9 +1265,6 @@ installmodules: modules installdirs @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(IDMAPLIBDIR) $(IDMAP_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CHARSETLIBDIR) $(CHARSET_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(AUTHLIBDIR) $(AUTH_MODULES) - @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CONFIGLIBDIR) $(CONFIG_MODULES) - @# These symlinks are required for the 'probing' of modules. - @# This mechanism should go at some point.. @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(PDBLIBDIR) ldapsam.@SHLIBEXT@ ldapsam_compat.@SHLIBEXT@ @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(AUTHLIBDIR) rhosts.@SHLIBEXT@ hostsequiv.@SHLIBEXT@ @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(AUTHLIBDIR) sam.@SHLIBEXT@ sam_ignoredomain.@SHLIBEXT@ @@ -1344,6 +1343,7 @@ showlayout: @echo " configdir: $(CONFIGDIR)" @echo " lockdir: $(LOCKDIR)" @echo " piddir: $(PIDDIR)" + @echo " swatdir: $(SWATDIR)" uninstall: uninstallman uninstallbin uninstallscripts uninstallmodules -- cgit From b5805b04da06fe37db70ebba4bfa33d3c3f6a9cb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 15 Mar 2004 16:20:22 +0000 Subject: removing extra comma in --with-fhs (This used to be commit ad1bf59a795e90e0a3757f1dd33d92442928e80c) --- source3/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index 3a15e9053b..806c53edaf 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -34,7 +34,7 @@ AC_ARG_WITH(fhs, privatedir="\${CONFIGDIR}/private" libdir="\${prefix}/lib/samba" configdir="${sysconfdir}/samba" - swatdir="\${DATADIR}/samba/swat", + swatdir="\${DATADIR}/samba/swat" ;; esac]) -- cgit From 8613940ce69c488dc19fb0c3e434f8801511ec2d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 15 Mar 2004 21:53:59 +0000 Subject: Use "unix netbios name" type unstring - 64 bytes long to manipulate netbios names in nmbd. Allows conversion from dos codepage mb strings (ie. SJIS) to expand to utf8 size on read. Jeremy. (This used to be commit b9da3e941d4233c2d3931f32767f3e51b214033e) --- source3/include/nameserv.h | 8 +++---- source3/include/safe_string.h | 1 + source3/include/smb.h | 3 +++ source3/nmbd/asyncdns.c | 9 ++++---- source3/nmbd/nmbd_become_dmb.c | 8 +++---- source3/nmbd/nmbd_become_lmb.c | 12 +++++----- source3/nmbd/nmbd_browserdb.c | 4 ++-- source3/nmbd/nmbd_browsesync.c | 22 +++++++++--------- source3/nmbd/nmbd_elections.c | 12 +++++----- source3/nmbd/nmbd_incomingdgrams.c | 44 ++++++++++++++++++------------------ source3/nmbd/nmbd_incomingrequests.c | 10 ++++---- source3/nmbd/nmbd_logonnames.c | 4 ++-- source3/nmbd/nmbd_mynames.c | 2 +- source3/nmbd/nmbd_namelistdb.c | 4 ++-- source3/nmbd/nmbd_nameregister.c | 6 ++--- source3/nmbd/nmbd_packets.c | 4 ++-- source3/nmbd/nmbd_processlogon.c | 4 ++-- source3/nmbd/nmbd_sendannounce.c | 4 ++-- source3/nmbd/nmbd_synclists.c | 12 +++++----- source3/nmbd/nmbd_winsproxy.c | 4 ++-- source3/nmbd/nmbd_winsserver.c | 8 +++---- source3/nmbd/nmbd_workgroupdb.c | 6 ++--- 22 files changed, 97 insertions(+), 94 deletions(-) diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h index 5362960d62..ec3d56c06b 100644 --- a/source3/include/nameserv.h +++ b/source3/include/nameserv.h @@ -226,8 +226,8 @@ struct name_record { /* Browser cache for synchronising browse lists. */ struct browse_cache_record { ubi_dlNode node[1]; - fstring lmb_name; - fstring work_group; + unstring lmb_name; + unstring work_group; struct in_addr ip; time_t sync_time; time_t death_time; /* The time the record must be removed. */ @@ -265,9 +265,9 @@ struct work_record { enum logon_state log_state; /* Work group info. */ - fstring work_group; + unstring work_group; int token; /* Used when communicating with backup browsers. */ - fstring local_master_browser_name; /* Current local master browser. */ + unstring local_master_browser_name; /* Current local master browser. */ /* Announce info. */ time_t lastannounce_time; diff --git a/source3/include/safe_string.h b/source3/include/safe_string.h index cb3f37c484..b22c5efcc9 100644 --- a/source3/include/safe_string.h +++ b/source3/include/safe_string.h @@ -139,6 +139,7 @@ size_t __unsafe_string_function_usage_here_char__(void); #define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1) #define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1) #define nstrcpy(d,s) safe_strcpy((d), (s),sizeof(nstring)-1) +#define unstrcpy(d,s) safe_strcpy((d), (s),sizeof(unstring)-1) /* the addition of the DEVELOPER checks in safe_strcpy means we must * update a lot of code. To make this a little easier here are some diff --git a/source3/include/smb.h b/source3/include/smb.h index 835066e263..7a1e8f87ba 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1509,7 +1509,10 @@ struct cnotify_fns { #include "smb_macros.h" #define MAX_NETBIOSNAME_LEN 16 +/* DOS character, NetBIOS namestring. Type used on the wire. */ typedef char nstring[MAX_NETBIOSNAME_LEN]; +/* Unix character, NetBIOS namestring. Type used to manipulate name in nmbd. */ +typedef char unstring[MAX_NETBIOSNAME_LEN*4]; /* A netbios name structure. */ struct nmb_name { diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c index dafbff7af2..653cb97fbb 100644 --- a/source3/nmbd/asyncdns.c +++ b/source3/nmbd/asyncdns.c @@ -27,7 +27,7 @@ static struct name_record *add_dns_result(struct nmb_name *question, struct in_addr addr) { int name_type = question->name_type; - fstring qname; + unstring qname; pull_ascii_nstring(qname, sizeof(qname), question->name); @@ -81,7 +81,7 @@ int asyncdns_fd(void) static void asyncdns_process(void) { struct query_record r; - fstring qname; + unstring qname; DEBUGLEVEL = -1; @@ -89,8 +89,7 @@ static void asyncdns_process(void) if (read_data(fd_in, (char *)&r, sizeof(r)) != sizeof(r)) break; - fstrcpy(qname, r.name.name); - + pull_ascii_nstring( qname, sizeof(qname), r.name.name); r.result.s_addr = interpret_addr(qname); if (write_data(fd_out, (char *)&r, sizeof(r)) != sizeof(r)) @@ -321,7 +320,7 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, struct name_record **n) { struct in_addr dns_ip; - nstring qname; + unstring qname; pull_ascii_nstring(qname, question->name); diff --git a/source3/nmbd/nmbd_become_dmb.c b/source3/nmbd/nmbd_become_dmb.c index c9b0a22580..fb1fb33a81 100644 --- a/source3/nmbd/nmbd_become_dmb.c +++ b/source3/nmbd/nmbd_become_dmb.c @@ -37,7 +37,7 @@ static void become_domain_master_fail(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *fail_name) { - fstring failname; + unstring failname; struct work_record *work; struct server_record *servrec; @@ -80,7 +80,7 @@ static void become_domain_master_stage2(struct subnet_record *subrec, uint16 nb_flags, int ttl, struct in_addr registered_ip) { - fstring regname; + unstring regname; struct work_record *work; struct server_record *servrec; @@ -200,7 +200,7 @@ static void become_domain_master_query_success(struct subnet_record *subrec, struct nmb_name *nmbname, struct in_addr ip, struct res_rec *rrec) { - fstring name; + unstring name; pull_ascii_nstring(name, sizeof(name), nmbname->name); /* If the given ip is not ours, then we can't become a domain @@ -241,7 +241,7 @@ static void become_domain_master_query_fail(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *question_name, int fail_code) { - fstring name; + unstring name; /* If the query was unicast, and the error is not NAM_ERR (name didn't exist), then this is a failure. Otherwise, not finding the name is what we want. */ diff --git a/source3/nmbd/nmbd_become_lmb.c b/source3/nmbd/nmbd_become_lmb.c index 8d66320f3e..c536deb6f4 100644 --- a/source3/nmbd/nmbd_become_lmb.c +++ b/source3/nmbd/nmbd_become_lmb.c @@ -33,7 +33,7 @@ extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */ void insert_permanent_name_into_unicast( struct subnet_record *subrec, struct nmb_name *nmbname, uint16 nb_type ) { - fstring name; + unstring name; struct name_record *namerec; if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL) { @@ -135,7 +135,7 @@ static void unbecome_local_master_success(struct subnet_record *subrec, struct in_addr released_ip) { BOOL force_new_election = False; - fstring relname; + unstring relname; memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL)); @@ -166,7 +166,7 @@ static void unbecome_local_master_fail(struct subnet_record *subrec, struct resp struct name_record *namerec; struct userdata_struct *userdata = rrec->userdata; BOOL force_new_election = False; - fstring failname; + unstring failname; memcpy((char *)&force_new_election, userdata->data, sizeof(BOOL)); @@ -330,7 +330,7 @@ static void become_local_master_stage2(struct subnet_record *subrec, struct server_record *sl; struct work_record *work; struct server_record *servrec; - fstring regname; + unstring regname; pull_ascii_nstring(regname, sizeof(regname), registered_name->name); work = find_workgroup_on_subnet( subrec, regname); @@ -410,7 +410,7 @@ static void become_local_master_fail2(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *fail_name) { - fstring failname; + unstring failname; struct work_record *work; DEBUG(0,("become_local_master_fail2: failed to register name %s on subnet %s. \ @@ -590,5 +590,5 @@ local_master_browser_name for workgroup %s to workgroup name.\n", } #endif - fstrcpy(work->local_master_browser_name, newname); + unstrcpy(work->local_master_browser_name, newname); } diff --git a/source3/nmbd/nmbd_browserdb.c b/source3/nmbd/nmbd_browserdb.c index d781259156..c92513fae8 100644 --- a/source3/nmbd/nmbd_browserdb.c +++ b/source3/nmbd/nmbd_browserdb.c @@ -106,8 +106,8 @@ struct browse_cache_record *create_browser_in_lmb_cache( const char *work_name, /* Allow the new lmb to miss an announce period before we remove it. */ browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 ); - fstrcpy( browc->lmb_name, browser_name); - fstrcpy( browc->work_group, work_name); + unstrcpy( browc->lmb_name, browser_name); + unstrcpy( browc->work_group, work_name); strupper_m( browc->lmb_name ); strupper_m( browc->work_group ); diff --git a/source3/nmbd/nmbd_browsesync.c b/source3/nmbd/nmbd_browsesync.c index f16d8603c9..15827e21ba 100644 --- a/source3/nmbd/nmbd_browsesync.c +++ b/source3/nmbd/nmbd_browsesync.c @@ -102,7 +102,7 @@ As a local master browser, send an announce packet to the domain master browser. static void announce_local_master_browser_to_domain_master_browser( struct work_record *work) { pstring outbuf; - fstring myname; + unstring myname; char *p; if(ismyip(work->dmb_addr)) { @@ -120,7 +120,7 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_ SCVAL(p,0,ANN_MasterAnnouncement); p++; - fstrcpy(myname, global_myname()); + unstrcpy(myname, global_myname()); strupper_m(myname); myname[15]='\0'; /* The call below does CH_UNIX -> CH_DOS conversion. JRA */ @@ -146,7 +146,7 @@ As a local master browser, do a sync with a domain master browser. static void sync_with_dmb(struct work_record *work) { - fstring dmb_name; + unstring dmb_name; if( DEBUGLVL( 2 ) ) { dbgtext( "sync_with_dmb:\n" ); @@ -156,7 +156,7 @@ static void sync_with_dmb(struct work_record *work) dbgtext( "for workgroup %s\n", work->work_group ); } - pull_ascii_nstring(dmb_name, sizeof(fstring), work->dmb_name.name); + pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name); sync_browse_lists(work, dmb_name, work->dmb_name.name_type, work->dmb_addr, False, True); } @@ -197,7 +197,7 @@ static void domain_master_node_status_success(struct subnet_record *subrec, p += 1; while (numnames--) { - fstring qname; + unstring qname; uint16 nb_flags; int name_type; @@ -278,7 +278,7 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec, struct nmb_name nmbname; struct userdata_struct *userdata; size_t size = sizeof(struct userdata_struct) + sizeof(fstring)+1; - fstring qname; + unstring qname; pull_ascii_nstring(qname, sizeof(qname), q_name->name); if( !(work = find_workgroup_on_subnet(subrec, qname)) ) { @@ -399,7 +399,7 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub struct in_addr from_ip) { struct work_record *work; - fstring server_name; + unstring server_name; server_name[0] = 0; @@ -420,7 +420,7 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub p += 1; while (numnames--) { - fstring qname; + unstring qname; uint16 nb_flags; int name_type; @@ -434,7 +434,7 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub if(!(nb_flags & NB_GROUP) && (name_type == 0x00) && server_name[0] == 0) { /* this is almost certainly the server netbios name */ - fstrcpy(server_name, qname); + unstrcpy(server_name, qname); continue; } @@ -460,7 +460,7 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub return; /* remember who the master is */ - fstrcpy(work->local_master_browser_name, server_name); + unstrcpy(work->local_master_browser_name, server_name); make_nmb_name(&nmbname, server_name, 0x20); work->dmb_name = nmbname; work->dmb_addr = from_ip; @@ -647,7 +647,7 @@ void sync_all_dmbs(time_t t) /* sync with a probability of 1/count */ for (work=unicast_subnet->workgrouplist; work; work = work->next) { if (strcmp(lp_workgroup(), work->work_group)) { - fstring dmb_name; + unstring dmb_name; if (((unsigned)sys_random()) % count != 0) continue; diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c index 24026d7cd9..470cf4277b 100644 --- a/source3/nmbd/nmbd_elections.c +++ b/source3/nmbd/nmbd_elections.c @@ -34,7 +34,7 @@ static void send_election_dgram(struct subnet_record *subrec, const char *workgr uint32 criterion, int timeup,const char *server_name) { pstring outbuf; - fstring srv_name; + unstring srv_name; char *p; DEBUG(2,("send_election_dgram: Sending election packet for workgroup %s on subnet %s\n", @@ -49,7 +49,7 @@ static void send_election_dgram(struct subnet_record *subrec, const char *workgr SIVAL(p,1,criterion); SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */ p += 13; - fstrcpy(srv_name, server_name); + unstrcpy(srv_name, server_name); strupper_m(srv_name); /* The following call does UNIX -> DOS charset conversion. */ pstrcpy_base(p, srv_name, outbuf); @@ -70,7 +70,7 @@ static void check_for_master_browser_success(struct subnet_record *subrec, struct nmb_name *answer_name, struct in_addr answer_ip, struct res_rec *rrec) { - fstring aname; + unstring aname; pull_ascii_nstring(aname, sizeof(aname), answer_name->name); DEBUG(3,("check_for_master_browser_success: Local master browser for workgroup %s exists at \ IP %s (just checking).\n", aname, inet_ntoa(answer_ip) )); @@ -85,7 +85,7 @@ static void check_for_master_browser_fail( struct subnet_record *subrec, struct nmb_name *question_name, int fail_code) { - fstring workgroup_name; + unstring workgroup_name; struct work_record *work; pull_ascii_nstring(workgroup_name,sizeof(workgroup_name),question_name->name); @@ -263,9 +263,9 @@ void process_election(struct subnet_record *subrec, struct packet_struct *p, cha int version = CVAL(buf,0); uint32 criterion = IVAL(buf,1); int timeup = IVAL(buf,5)/1000; - fstring server_name; + unstring server_name; struct work_record *work; - fstring workgroup_name; + unstring workgroup_name; pull_ascii_nstring(server_name, sizeof(server_name), buf+13); pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name); diff --git a/source3/nmbd/nmbd_incomingdgrams.c b/source3/nmbd/nmbd_incomingdgrams.c index 1450610e19..53b1947157 100644 --- a/source3/nmbd/nmbd_incomingdgrams.c +++ b/source3/nmbd/nmbd_incomingdgrams.c @@ -97,13 +97,13 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p { struct dgram_packet *dgram = &p->packet.dgram; int ttl = IVAL(buf,1)/1000; - fstring announce_name; + unstring announce_name; uint32 servertype = IVAL(buf,23); fstring comment; struct work_record *work; struct server_record *servrec; - fstring work_name; - fstring source_name; + unstring work_name; + unstring source_name; START_PROFILE(host_announce); @@ -144,7 +144,7 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p */ if(strequal(work_name, global_myname())) - fstrcpy(work_name,lp_workgroup()); + unstrcpy(work_name,lp_workgroup()); /* * We are being very agressive here in adding a workgroup @@ -198,12 +198,12 @@ void process_workgroup_announce(struct subnet_record *subrec, struct packet_stru { struct dgram_packet *dgram = &p->packet.dgram; int ttl = IVAL(buf,1)/1000; - fstring workgroup_announce_name; - fstring master_name; + unstring workgroup_announce_name; + unstring master_name; uint32 servertype = IVAL(buf,23); struct work_record *work; - fstring source_name; - fstring dest_name; + unstring source_name; + unstring dest_name; START_PROFILE(workgroup_announce); @@ -255,13 +255,13 @@ void process_local_master_announce(struct subnet_record *subrec, struct packet_s { struct dgram_packet *dgram = &p->packet.dgram; int ttl = IVAL(buf,1)/1000; - fstring server_name; + unstring server_name; uint32 servertype = IVAL(buf,23); fstring comment; - fstring work_name; + unstring work_name; struct work_record *work; struct server_record *servrec; - fstring source_name; + unstring source_name; START_PROFILE(local_master_announce); @@ -369,7 +369,7 @@ done: void process_master_browser_announce(struct subnet_record *subrec, struct packet_struct *p,char *buf) { - fstring local_master_name; + unstring local_master_name; struct work_record *work; struct browse_cache_record *browrec; @@ -425,11 +425,11 @@ void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct int osmajor=CVAL(buf,5); /* major version of node software */ int osminor=CVAL(buf,6); /* minor version of node software */ int ttl = SVAL(buf,7); - fstring announce_name; + unstring announce_name; struct work_record *work; struct server_record *servrec; - fstring work_name; - fstring source_name; + unstring work_name; + unstring source_name; fstring comment; char *s = buf+9; @@ -479,7 +479,7 @@ originate from OS/2 Warp client. Ignoring packet.\n")); */ if(strequal(work_name, global_myname())) - fstrcpy(work_name,lp_workgroup()); + unstrcpy(work_name,lp_workgroup()); /* * We are being very agressive here in adding a workgroup @@ -541,11 +541,11 @@ static void send_backup_list_response(struct subnet_record *subrec, char outbuf[1024]; char *p, *countptr; unsigned int count = 0; - fstring send_to_namestr; + unstring send_to_namestr; #if 0 struct server_record *servrec; #endif - fstring myname; + unstring myname; memset(outbuf,'\0',sizeof(outbuf)); @@ -565,7 +565,7 @@ static void send_backup_list_response(struct subnet_record *subrec, /* We always return at least one name - our own. */ count = 1; - fstrcpy(myname, global_myname()); + unstrcpy(myname, global_myname()); strupper_m(myname); myname[15]='\0'; push_pstring_base(p, myname, outbuf); @@ -642,7 +642,7 @@ void process_get_backup_list_request(struct subnet_record *subrec, unsigned char max_number_requested = CVAL(buf,0); uint32 token = IVAL(buf,1); /* Sender's key index for the workgroup. */ int name_type = dgram->dest_name.name_type; - fstring workgroup_name; + unstring workgroup_name; struct subnet_record *search_subrec = subrec; START_PROFILE(get_backup_list); @@ -774,7 +774,7 @@ void process_announce_request(struct subnet_record *subrec, struct packet_struct { struct dgram_packet *dgram = &p->packet.dgram; struct work_record *work; - fstring workgroup_name; + unstring workgroup_name; START_PROFILE(announce_request); @@ -814,7 +814,7 @@ done: void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf) { struct dgram_packet *dgram = &p->packet.dgram; - fstring workgroup_name; + unstring workgroup_name; START_PROFILE(lm_announce_request); diff --git a/source3/nmbd/nmbd_incomingrequests.c b/source3/nmbd/nmbd_incomingrequests.c index d43cefc0df..9214594096 100644 --- a/source3/nmbd/nmbd_incomingrequests.c +++ b/source3/nmbd/nmbd_incomingrequests.c @@ -58,7 +58,7 @@ void process_name_release_request(struct subnet_record *subrec, struct nmb_packet *nmb = &p->packet.nmb; struct in_addr owner_ip; struct nmb_name *question = &nmb->question.question_name; - fstring qname; + unstring qname; BOOL bcast = nmb->header.nm_flags.bcast; uint16 nb_flags = get_nb_flags(nmb->additional->rdata); BOOL group = (nb_flags & NB_GROUP) ? True : False; @@ -275,7 +275,7 @@ We put our own names first, then in alphabetical order. static int status_compare(char *n1,char *n2) { - fstring name1, name2; + unstring name1, name2; int l1,l2,l3; memset(name1, '\0', sizeof(name1)); @@ -300,7 +300,7 @@ static int status_compare(char *n1,char *n2) (l1!=l3 || strncmp(n1,global_myname(),l3) != 0)) return 1; - return memcmp(n1,n2,sizeof(fstring)); + return memcmp(n1,n2,sizeof(name1)); } /**************************************************************************** @@ -310,7 +310,7 @@ static int status_compare(char *n1,char *n2) void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - fstring qname; + unstring qname; int ques_type = nmb->question.question_name.name_type; char rdata[MAX_DGRAM_SIZE]; char *countptr, *buf, *bufend, *buf0; @@ -344,7 +344,7 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name), while (buf < bufend) { if( (namerec->data.source == SELF_NAME) || (namerec->data.source == PERMANENT_NAME) ) { int name_type = namerec->name.name_type; - fstring name; + unstring name; pull_ascii_nstring(name, sizeof(name), namerec->name.name); strupper_m(name); diff --git a/source3/nmbd/nmbd_logonnames.c b/source3/nmbd/nmbd_logonnames.c index b6e841139f..e426430591 100644 --- a/source3/nmbd/nmbd_logonnames.c +++ b/source3/nmbd/nmbd_logonnames.c @@ -35,7 +35,7 @@ static void become_logon_server_fail(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *fail_name) { - fstring failname; + unstring failname; struct work_record *work; struct server_record *servrec; @@ -76,7 +76,7 @@ static void become_logon_server_success(struct subnet_record *subrec, uint16 nb_flags, int ttl, struct in_addr registered_ip) { - fstring reg_name; + unstring reg_name; struct work_record *work; struct server_record *servrec; diff --git a/source3/nmbd/nmbd_mynames.c b/source3/nmbd/nmbd_mynames.c index 83a8361ed9..07247d5495 100644 --- a/source3/nmbd/nmbd_mynames.c +++ b/source3/nmbd/nmbd_mynames.c @@ -93,7 +93,7 @@ static void insert_refresh_name_into_unicast( struct subnet_record *subrec, } if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL) { - fstring name; + unstring name; pull_ascii_nstring(name, sizeof(name), nmbname->name); /* The name needs to be created on the unicast subnet. */ (void)add_name_to_subnet( unicast_subnet, name, diff --git a/source3/nmbd/nmbd_namelistdb.c b/source3/nmbd/nmbd_namelistdb.c index 9f89abdbb2..bb14ff7641 100644 --- a/source3/nmbd/nmbd_namelistdb.c +++ b/source3/nmbd/nmbd_namelistdb.c @@ -45,7 +45,7 @@ void set_samba_nb_type(void) static void upcase_name( struct nmb_name *target, struct nmb_name *source ) { int i; - fstring targ; + unstring targ; fstring scope; if( NULL != source ) @@ -255,7 +255,7 @@ void standard_success_register(struct subnet_record *subrec, namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME ); if( NULL == namerec ) { - fstring name; + unstring name; pull_ascii_nstring(name, sizeof(name), nmbname->name); add_name_to_subnet( subrec, name, nmbname->name_type, nb_flags, ttl, SELF_NAME, 1, ®istered_ip ); diff --git a/source3/nmbd/nmbd_nameregister.c b/source3/nmbd/nmbd_nameregister.c index 4fbdd143e1..4e11881f06 100644 --- a/source3/nmbd/nmbd_nameregister.c +++ b/source3/nmbd/nmbd_nameregister.c @@ -85,7 +85,7 @@ static void register_name_response(struct subnet_record *subrec, */ #if 1 /* OLD_SAMBA_SERVER_HACK */ - fstring ans_name; + unstring ans_name; pull_ascii_nstring(ans_name, sizeof(ans_name), answer_name->name); if((nmb->header.rcode == ACT_ERR) && strequal(lp_workgroup(), ans_name) && (answer_name->name_type == 0x1b)) { @@ -418,7 +418,7 @@ static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags, struct subnet_record *subrec; char **wins_tags; struct in_addr *ip_list; - fstring name; + unstring name; for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) ) num_ips++; @@ -476,7 +476,7 @@ void register_name(struct subnet_record *subrec, errno = 0; push_ascii_nstring(nname, name); if (errno == E2BIG) { - fstring tname; + unstring tname; pull_ascii_nstring(tname, sizeof(tname), nname); DEBUG(0,("register_name: NetBIOS name %s is too long. Truncating to %s\n", name, tname)); diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c index b5cbaab00b..d8b50a1b2e 100644 --- a/source3/nmbd/nmbd_packets.c +++ b/source3/nmbd/nmbd_packets.c @@ -1034,7 +1034,7 @@ static void process_browse_packet(struct packet_struct *p, char *buf,int len) int command = CVAL(buf,0); struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p); char scope[64]; - fstring src_name; + unstring src_name; /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */ pull_ascii(scope, dgram->dest_name.scope, 64, 64, STR_TERMINATE); @@ -1121,7 +1121,7 @@ static void process_lanman_packet(struct packet_struct *p, char *buf,int len) int command = SVAL(buf,0); struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p); char scope[64]; - fstring src_name; + unstring src_name; /* Drop the packet if it's a different NetBIOS scope, or the source is from one of our names. */ diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index ff2aea6c08..da93224043 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -235,7 +235,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", { fstring getdc_str; - nstring source_name; + fstring source_name; char *q = buf + 2; fstring asccomp; @@ -440,7 +440,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", send_mailslot(True, getdc, outbuf,PTR_DIFF(q,outbuf), global_myname(), 0x0, - dgram->source_name.name, + source_name, dgram->source_name.name_type, p->ip, *iface_ip(p->ip), p->port); break; diff --git a/source3/nmbd/nmbd_sendannounce.c b/source3/nmbd/nmbd_sendannounce.c index 87908e352c..6e50d2f2ff 100644 --- a/source3/nmbd/nmbd_sendannounce.c +++ b/source3/nmbd/nmbd_sendannounce.c @@ -525,7 +525,7 @@ void browse_sync_remote(time_t t) struct work_record *work; pstring outbuf; char *p; - fstring myname; + unstring myname; if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL))) return; @@ -558,7 +558,7 @@ for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name )); SCVAL(p,0,ANN_MasterAnnouncement); p++; - fstrcpy(myname, global_myname()); + unstrcpy(myname, global_myname()); strupper_m(myname); myname[15]='\0'; push_pstring_base(p, myname, outbuf); diff --git a/source3/nmbd/nmbd_synclists.c b/source3/nmbd/nmbd_synclists.c index 424af1e2e3..86f1f760fd 100644 --- a/source3/nmbd/nmbd_synclists.c +++ b/source3/nmbd/nmbd_synclists.c @@ -31,8 +31,8 @@ struct sync_record { struct sync_record *next, *prev; - fstring workgroup; - fstring server; + unstring workgroup; + unstring server; pstring fname; struct in_addr ip; pid_t pid; @@ -148,8 +148,8 @@ done: ZERO_STRUCTP(s); - fstrcpy(s->workgroup, work->work_group); - fstrcpy(s->server, name); + unstrcpy(s->workgroup, work->work_group); + unstrcpy(s->server, name); s->ip = ip; slprintf(s->fname, sizeof(pstring)-1, @@ -206,7 +206,7 @@ static void complete_one(struct sync_record *s, sname, lp_max_ttl()); if (work) { /* remember who the master is */ - fstrcpy(work->local_master_browser_name, comment); + unstrcpy(work->local_master_browser_name, comment); } } return; @@ -243,7 +243,7 @@ static void complete_one(struct sync_record *s, static void complete_sync(struct sync_record *s) { XFILE *f; - fstring server, type_str; + unstring server, type_str; unsigned type; pstring comment; pstring line; diff --git a/source3/nmbd/nmbd_winsproxy.c b/source3/nmbd/nmbd_winsproxy.c index d91818698e..cce168adb2 100644 --- a/source3/nmbd/nmbd_winsproxy.c +++ b/source3/nmbd/nmbd_winsproxy.c @@ -30,7 +30,7 @@ static void wins_proxy_name_query_request_success( struct subnet_record *subrec, struct userdata_struct *userdata, struct nmb_name *nmbname, struct in_addr ip, struct res_rec *rrec) { - fstring name; + unstring name; struct packet_struct *original_packet; struct subnet_record *orig_broadcast_subnet; struct name_record *namerec; @@ -193,7 +193,7 @@ void make_wins_proxy_name_query_request( struct subnet_record *subrec, long *ud[(sizeof(struct userdata_struct) + sizeof(struct subrec *) + sizeof(struct packet_struct *))/sizeof(long *) + 1]; struct userdata_struct *userdata = (struct userdata_struct *)ud; - fstring qname; + unstring qname; memset(ud, '\0', sizeof(ud)); diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c index fd7718e2a6..0f0190adb6 100644 --- a/source3/nmbd/nmbd_winsserver.c +++ b/source3/nmbd/nmbd_winsserver.c @@ -744,7 +744,7 @@ querying for name %s in order to replace it and this reply.\n", nmb_namestr(ques void wins_process_name_registration_request(struct subnet_record *subrec, struct packet_struct *p) { - fstring name; + unstring name; struct nmb_packet *nmb = &p->packet.nmb; struct nmb_name *question = &nmb->question.question_name; BOOL bcast = nmb->header.nm_flags.bcast; @@ -1119,7 +1119,7 @@ void wins_process_multihomed_name_registration_request( struct subnet_record *su struct in_addr from_ip; BOOL group = (nb_flags & NB_GROUP) ? True : False; struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0"); - fstring qname; + unstring qname; putip((char *)&from_ip,&nmb->additional->rdata[2]); @@ -1479,7 +1479,7 @@ void wins_process_name_query_request(struct subnet_record *subrec, struct nmb_packet *nmb = &p->packet.nmb; struct nmb_name *question = &nmb->question.question_name; struct name_record *namerec = NULL; - fstring qname; + unstring qname; DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n", nmb_namestr(question), inet_ntoa(p->ip) )); @@ -1845,7 +1845,7 @@ void wins_write_database(BOOL background) DEBUGADD(4,("%2x\n", namerec->data.nb_flags )); if( namerec->data.source == REGISTER_NAME ) { - fstring name; + unstring name; pull_ascii_nstring(name, sizeof(name), namerec->name.name); x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */ (int)namerec->data.death_time); diff --git a/source3/nmbd/nmbd_workgroupdb.c b/source3/nmbd/nmbd_workgroupdb.c index 3efef49c04..8880cb58bb 100644 --- a/source3/nmbd/nmbd_workgroupdb.c +++ b/source3/nmbd/nmbd_workgroupdb.c @@ -61,13 +61,13 @@ static struct work_record *create_workgroup(const char *name, int ttl) errno = 0; push_ascii_nstring(nname, name); if (errno == E2BIG) { - fstring tname; + unstring tname; pull_ascii_nstring(tname, sizeof(tname), nname); - fstrcpy(work->work_group,tname); + unstrcpy(work->work_group,tname); DEBUG(0,("create_workgroup: workgroup name %s is too long. Truncating to %s\n", name, tname)); } else { - fstrcpy(work->work_group,name); + unstrcpy(work->work_group,name); } work->serverlist = NULL; -- cgit From c377ae98b1e22f95609da7c13ec1868c7a20a9ff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Mar 2004 00:10:34 +0000 Subject: Avoid mb conversion overflow when sending an announcement. Jeremy. (This used to be commit 7a62d6215d32e664345d10b87ab4e4ddeda5dc2e) --- source3/nmbd/nmbd_sendannounce.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/nmbd/nmbd_sendannounce.c b/source3/nmbd/nmbd_sendannounce.c index 6e50d2f2ff..a74dd99196 100644 --- a/source3/nmbd/nmbd_sendannounce.c +++ b/source3/nmbd/nmbd_sendannounce.c @@ -92,6 +92,7 @@ static void send_announcement(struct subnet_record *subrec, int announce_type, const char *server_name, int server_type, const char *server_comment) { pstring outbuf; + unstring upper_server_name; char *p; memset(outbuf,'\0',sizeof(outbuf)); @@ -103,7 +104,9 @@ static void send_announcement(struct subnet_record *subrec, int announce_type, SCVAL(p,0,updatecount); SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */ - push_string(NULL, p+5, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE); + safe_strcpy(upper_server_name, server_name, sizeof(upper_server_name)-1); + strupper_m(upper_server_name); + push_string(NULL, p+5, upper_server_name, 16, STR_ASCII|STR_TERMINATE); SCVAL(p,21,lp_major_announce_version()); /* Major version. */ SCVAL(p,22,lp_minor_announce_version()); /* Minor version. */ -- cgit From 76e86e88c3d578ad47d4bc9ef7e8e6c035715dea Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 16 Mar 2004 06:56:20 +0000 Subject: Make sure we don't clobber the stack when response consists of the empty string. (This used to be commit e522663717f6b6141580f34502ad8686d326f8c8) --- source3/nsswitch/winbindd_wins.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/nsswitch/winbindd_wins.c b/source3/nsswitch/winbindd_wins.c index bc982d0044..a1eef159c0 100644 --- a/source3/nsswitch/winbindd_wins.c +++ b/source3/nsswitch/winbindd_wins.c @@ -201,7 +201,10 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state) } if (i != 0) { /* Clear out the newline character */ - response[strlen(response)-1] = ' '; + /* But only if there is something in there, + otherwise we clobber something in the stack */ + if (strlen(response)) + response[strlen(response)-1] = ' '; } fstrcat(response,addr); fstrcat(response,"\t"); -- cgit From 1df61db0720b0d5372ffb43cf2fd60d72e438728 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 16 Mar 2004 16:44:54 +0000 Subject: BUG 1165, 1126: Fix bug with secondary groups (security = ads) and winbind use default domain = yes (This used to be commit ca971cf76e5fbb33d51b1fdfa92e4d13b2e150b6) --- source3/auth/auth_server.c | 21 ++++--- source3/auth/auth_unix.c | 2 +- source3/auth/auth_util.c | 137 +++++++++++++++++++++++++-------------------- source3/smbd/sesssetup.c | 12 ++-- 4 files changed, 96 insertions(+), 76 deletions(-) diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c index 41adc21784..bc611ec229 100644 --- a/source3/auth/auth_server.c +++ b/source3/auth/auth_server.c @@ -377,18 +377,17 @@ use this machine as the password server.\n")); cli_ulogoff(cli); if (NT_STATUS_IS_OK(nt_status)) { - struct passwd *pass = Get_Pwnam(user_info->internal_username.str); - if (pass) { - nt_status = make_server_info_pw(server_info, pass); - } else { - auth_add_user_script(user_info->domain.str, user_info->internal_username.str); - pass = Get_Pwnam(user_info->internal_username.str); + fstring real_username; + struct passwd *pass; - if (pass) { - nt_status = make_server_info_pw(server_info, pass); - } else { - nt_status = NT_STATUS_NO_SUCH_USER; - } + if ( (pass = smb_getpwnam( user_info->internal_username.str, + real_username, True )) != NULL ) + { + nt_status = make_server_info_pw(server_info, pass->pw_name, pass); + } + else + { + nt_status = NT_STATUS_NO_SUCH_USER; } } diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c index b9de6f7acb..f744cba0c4 100644 --- a/source3/auth/auth_unix.c +++ b/source3/auth/auth_unix.c @@ -108,7 +108,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context, if (NT_STATUS_IS_OK(nt_status)) { if (pass) { - make_server_info_pw(server_info, pass); + make_server_info_pw(server_info, pass->pw_name, pass); } else { /* we need to do somthing more useful here */ nt_status = NT_STATUS_NO_SUCH_USER; diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index b21b00ca8d..c74f01ab67 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -757,6 +757,7 @@ Fill a server_info struct from a SAM_ACCOUNT with their groups ***************************************************************************/ static NTSTATUS add_user_groups(auth_serversupplied_info **server_info, + const char * unix_username, SAM_ACCOUNT *sampass, uid_t uid, gid_t gid) { @@ -770,7 +771,7 @@ static NTSTATUS add_user_groups(auth_serversupplied_info **server_info, BOOL is_guest; uint32 rid; - nt_status = get_user_groups(pdb_get_username(sampass), uid, gid, + nt_status = get_user_groups(unix_username, uid, gid, &n_groupSIDs, &groupSIDs, &unix_groups); if (!NT_STATUS_IS_OK(nt_status)) { @@ -845,9 +846,11 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, passwd_free(&pwd); - if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass, + if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass), + sampass, (*server_info)->uid, - (*server_info)->gid))) { + (*server_info)->gid))) + { free_server_info(server_info); return nt_status; } @@ -870,7 +873,9 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, to a SAM_ACCOUNT ***************************************************************************/ -NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd) +NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, + char *unix_username, + struct passwd *pwd) { NTSTATUS nt_status; SAM_ACCOUNT *sampass = NULL; @@ -883,11 +888,13 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, const struc (*server_info)->sam_account = sampass; - if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass, pwd->pw_uid, pwd->pw_gid))) { + if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username, + sampass, pwd->pw_uid, pwd->pw_gid))) + { return nt_status; } - (*server_info)->unix_name = smb_xstrdup(pwd->pw_name); + (*server_info)->unix_name = smb_xstrdup(unix_username); (*server_info)->sam_fill_level = SAM_FILL_ALL; (*server_info)->uid = pwd->pw_uid; @@ -946,52 +953,30 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **sam_account) { fstring dom_user; + fstring real_username; struct passwd *passwd; fstr_sprintf(dom_user, "%s%s%s", domain, lp_winbind_separator(), username); - passwd = Get_Pwnam(dom_user); - - if ( passwd ) { - char *p; - - /* make sure we get the case of the username correct */ - /* work around 'winbind use default domain = yes' */ - - p = strchr( passwd->pw_name, *lp_winbind_separator() ); - if ( !p ) - fstr_sprintf(dom_user, "%s%s%s", domain, - lp_winbind_separator(), passwd->pw_name); - else - fstrcpy( dom_user, passwd->pw_name ); - } - else { - /* if the lookup for DOMAIN\username failed, try again - with just 'username'. This is need for accessing the server - as a trust user that actually maps to a local account */ - - fstrcpy( dom_user, username ); - passwd = Get_Pwnam( dom_user ); - - /* make sure we get the case of the username correct */ - if ( passwd ) - fstrcpy( dom_user, passwd->pw_name ); - } + /* get the passwd struct but don't create the user if he/she + does not exist. We were explicitly called from a following + a winbindd authentication request so we should assume that + nss_winbindd is working */ - if ( !passwd ) + if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) ) return NT_STATUS_NO_SUCH_USER; *uid = passwd->pw_uid; *gid = passwd->pw_gid; - /* This is pointless -- there is no suport for differeing + /* This is pointless -- there is no suport for differing unix and windows names. Make sure to always store the one we actually looked up and succeeded. Have I mentioned why I hate the 'winbind use default domain' parameter? --jerry */ - *found_username = talloc_strdup(mem_ctx, dom_user); + *found_username = talloc_strdup( mem_ctx, real_username ); DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username)); @@ -1005,40 +990,72 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, the username if we fallback to the username only. ****************************************************************************/ -struct passwd *smb_getpwnam( char *domuser ) +struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create ) { struct passwd *pw = NULL; char *p; fstring mapped_username; + + /* we only save a copy of the username it has been mangled + by winbindd use default domain */ + + save_username[0] = '\0'; + + /* save a local copy of the username and run it through the + username map */ + + fstrcpy( mapped_username, domuser ); + map_username( mapped_username ); + + p = strchr_m( mapped_username, *lp_winbind_separator() ); + + /* code for a DOMAIN\user string */ + + if ( p ) { + pw = Get_Pwnam( domuser ); + if ( pw ) { + /* make sure we get the case of the username correct */ + /* work around 'winbind use default domain = yes' */ - pw = Get_Pwnam( domuser ); - if ( pw ) - return pw; - - /* fallback to looking up just the username */ + if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) { + char *domain; + + domain = mapped_username; + *p = '\0'; + fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name); + } + else + fstrcpy( save_username, pw->pw_name ); - p = strchr( domuser, *lp_winbind_separator() ); + /* whew -- done! */ + return pw; + } - if ( p ) { - p += 1; + /* setup for lookup of just the username */ + p++; fstrcpy( mapped_username, p ); - map_username( mapped_username ); + + } + + /* just lookup a plain username */ + + pw = Get_Pwnam(mapped_username); + + /* Create local user if requested. */ + + if ( !pw && create ) { + /* Don't add a machine account. */ + if (mapped_username[strlen(mapped_username)-1] == '$') + return NULL; + + auth_add_user_script(NULL, mapped_username); pw = Get_Pwnam(mapped_username); - if (!pw) { - /* Don't add a machine account. */ - if (mapped_username[strlen(mapped_username)-1] == '$') - return NULL; - - /* Create local user if requested. */ - p = strchr( mapped_username, *lp_winbind_separator() ); - if (p) - p += 1; - else - p = mapped_username; - auth_add_user_script(NULL, p); - return Get_Pwnam(p); - } } + + /* one last check for a valid passwd struct */ + + if ( pw ) + fstrcpy( save_username, pw->pw_name ); return pw; } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c66ccfd8eb..864d69653c 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -143,7 +143,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB ticket; char *client, *p, *domain; fstring netbios_domain_name; - const struct passwd *pw; + struct passwd *pw; char *user; int sess_vuid; NTSTATUS ret; @@ -154,6 +154,7 @@ static int reply_spnego_kerberos(connection_struct *conn, uint8 tok_id[2]; BOOL foreign = False; DATA_BLOB nullblob = data_blob(NULL, 0); + fstring real_username; ZERO_STRUCT(ticket); ZERO_STRUCT(auth_data); @@ -239,7 +240,9 @@ static int reply_spnego_kerberos(connection_struct *conn, asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client); - pw = smb_getpwnam( user ); + /* lookup the passwd struct, create a new user if necessary */ + + pw = smb_getpwnam( user, real_username, True ); if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); @@ -251,10 +254,11 @@ static int reply_spnego_kerberos(connection_struct *conn, /* setup the string used by %U */ - sub_set_smb_name(pw->pw_name); + sub_set_smb_name( real_username ); reload_services(True); - if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) { + if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw))) + { DEBUG(1,("make_server_info_from_pw failed!\n")); SAFE_FREE(user); SAFE_FREE(client); -- cgit From b1d5261bde86abdd90701897ebc2d03211b65c33 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 16 Mar 2004 17:07:18 +0000 Subject: merging print change notify fix from HP appliance. Also might address some one the issues in BUG 1007 (This used to be commit b80e3553bf1b7f8d1435f3144082577f2e30c3a9) --- source3/printing/printing.c | 18 ++++++++- source3/rpc_server/srv_spoolss_nt.c | 78 ------------------------------------- 2 files changed, 16 insertions(+), 80 deletions(-) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ed19c01f24..e4ef1f52d0 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -534,8 +534,22 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) /* Send notify updates for what has changed */ - if ( ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob)) ) - pjob_store_notify( snum, jobid, (struct printjob *)old_data.dptr, pjob ); + if ( ret ) { + struct printjob old_pjob; + + if ( old_data.dsize ) + { + if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 ) + { + pjob_store_notify( snum, jobid, &old_pjob , pjob ); + free_nt_devicemode( &old_pjob.nt_devmode ); + } + } + else { + /* new job */ + pjob_store_notify( snum, jobid, NULL, pjob ); + } + } done: SAFE_FREE( old_data.dptr ); diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index b5f5bffbb4..edd62fa8f6 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -1099,58 +1099,6 @@ static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, voi return True; } -/* ENUMJOB last timestamp list. */ -struct ejts_list { - struct ejts_list *next, *prev; - char *printer_name; - struct timeval tv; -}; - -static struct ejts_list *ejts_head; - -static struct ejts_list *find_enumjobs_timestamp(const char *printer_name) -{ - struct ejts_list *ejtsl; - - for( ejtsl = ejts_head; ejtsl; ejtsl = ejtsl->next) - if (strequal(ejtsl->printer_name, printer_name)) - return ejtsl; - return NULL; -} - -static void set_enumjobs_timestamp(int snum) -{ - const char *printer_name = lp_const_servicename(snum); - struct ejts_list *ejtsl = find_enumjobs_timestamp(printer_name); - - if (!ejtsl) { - ejtsl = (struct ejts_list *)malloc(sizeof(struct ejts_list)); - if (!ejtsl) - return; - ejtsl->printer_name = strdup(printer_name); - if (!ejtsl->printer_name) { - SAFE_FREE(ejtsl); - return; - } - DLIST_ADD(ejts_head, ejtsl); - } - - gettimeofday(&ejtsl->tv, NULL); -} - -static int timeval_diff(struct timeval *tv1, struct timeval *tv2) -{ - if (tv1->tv_sec > tv2->tv_sec) - return 1; - if (tv1->tv_sec < tv2->tv_sec) - return -1; - if (tv1->tv_usec > tv2->tv_usec) - return 1; - if (tv1->tv_usec < tv2->tv_usec) - return -1; - return 0; -} - /******************************************************************** Receive a notify2 message list ********************************************************************/ @@ -1214,29 +1162,6 @@ static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, siz notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len ); msg_ptr += msg_len; - /* See if it is still relevent. */ - if (notify.type == JOB_NOTIFY_TYPE) { - BOOL status_is_deleting = False; - - if (notify.field == JOB_NOTIFY_STATUS && (notify.notify.value[0] & (JOB_STATUS_DELETING|JOB_STATUS_DELETED))) - status_is_deleting = True; - - if (!status_is_deleting) { - struct ejts_list *ejtsl = find_enumjobs_timestamp(notify.printer); - - if (ejtsl && (timeval_diff(&ejtsl->tv, &msg_tv) > 0)) { - - DEBUG(10, ("receive_notify2_message_list: enumjobs ts = %u, %u, msg ts = %u, %u discarding\n", - (unsigned int)ejtsl->tv.tv_sec, (unsigned int)ejtsl->tv.tv_usec, - (unsigned int)msg_tv.tv_sec, (unsigned int)msg_tv.tv_usec )); - - /* Message no longer relevent. Ignore it. */ - if ( notify.len != 0 ) - SAFE_FREE( notify.notify.data ); - continue; - } - } - } /* add to correct list in container */ notify_msg_ctr_addmsg( &messages, ¬ify ); @@ -6519,7 +6444,6 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message)); if (*returned == 0) { - set_enumjobs_timestamp(snum); SAFE_FREE(queue); return WERR_OK; } @@ -6527,11 +6451,9 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO switch (level) { case 1: wret = enumjobs_level1(queue, snum, buffer, offered, needed, returned); - set_enumjobs_timestamp(snum); return wret; case 2: wret = enumjobs_level2(queue, snum, buffer, offered, needed, returned); - set_enumjobs_timestamp(snum); return wret; default: SAFE_FREE(queue); -- cgit From ba042a96cdb8e4b12791481725fbbf193df130b7 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 16 Mar 2004 17:21:06 +0000 Subject: Fix check_path_syntax() for multibyte encodings which have no '\' as second byte. This is intermediate fix as discussed with Jeremy until we move check_path_syntax() to UCS2 internally where all ambiguity is resolved. Please add other encodings into charcnv.c with such property. (This used to be commit c8c66337494c63173a6aba4286a843875302da63) --- source3/lib/charcnv.c | 20 ++++++++++++++++++++ source3/smbd/reply.c | 4 +++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 20af806d90..b06d869bcc 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -41,6 +41,15 @@ static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS]; static BOOL conv_silent; /* Should we do a debug if the conversion fails ? */ +/* Unsafe unix charsets which could contain '\\' as second byte of mb character */ +static const char *conv_unsafe_charsets[] = { + "CP932", + "EUC-JP", + NULL}; +/* Global variable which is set to True in init_iconv() if unix charset is unsafe + w.r.t. '\\' in second byte of mb character. Otherwise it is set to False. +*/ +BOOL is_unix_charset_unsafe; /** * Return the name of a charset to give to iconv(). @@ -105,6 +114,7 @@ void init_iconv(void) { int c1, c2; BOOL did_reload = False; + const char **unsafe_charset = conv_unsafe_charsets; /* so that charset_name() works we need to get the UNIX<->UCS2 going first */ @@ -146,6 +156,16 @@ void init_iconv(void) init_valid_table(); conv_silent = False; } + + while(*unsafe_charset && strcmp(*unsafe_charset, conv_handles[CH_UCS2][CH_UNIX]->to_name)) { + unsafe_charset++; + } + + if (*unsafe_charset) { + is_unix_charset_unsafe = True; + } else { + is_unix_charset_unsafe = False; + } } /** diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index bca7a75fbb..48894308d1 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -33,6 +33,7 @@ extern char magic_char; extern BOOL case_sensitive; extern BOOL case_preserve; extern BOOL short_case_preserve; +extern BOOL is_unix_charset_unsafe; extern int global_oplock_break; unsigned int smb_echo_count = 0; @@ -110,7 +111,8 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname) } s++; } else { - if ((*s & 0x80) && IS_DIRECTORY_SEP(s[1])) { + /* Activate this codepath only if we know that Unix charset may contain unsafe '\\' */ + if ((is_unix_charset_unsafe == True) && ((*s & 0x80) && IS_DIRECTORY_SEP(s[1]))) { /* * Potential mb char with second char a directory separator. * All the encodings we care about are 2 byte only, so do a -- cgit From 4b27ffd821b8b46d837afda1c7602359314263d5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 16 Mar 2004 19:06:30 +0000 Subject: BUG 979 -- fix quota display on AIX; patch from Heinrich.Mislik@univie.ac.at (Heinrich Mislik) (This used to be commit 8f9bedaeb1b3b102fa6b23da1f6b03eb0e015359) --- source3/smbd/quotas.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c index c0b2db6173..e439c1e571 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -994,7 +994,11 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB #elif defined(AIX) /* AIX has both USER and GROUP quotas: Get the USER quota (ohnielse@fysik.dtu.dk) */ + save_re_uid(); + if (set_re_uid() != 0) + return False; r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D); + restore_re_uid(); #else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */ r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D); #endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */ -- cgit From 2f8a18c093938f7aa31541f9b56da9be23fb861b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 16 Mar 2004 20:32:14 +0000 Subject: merges from 3.0 (This used to be commit fed98658a5cc82e9fdc65aa73f74e118c1104178) --- source3/auth/auth_util.c | 7 +++++-- source3/nsswitch/winbindd.c | 2 +- source3/nsswitch/winbindd_group.c | 4 +++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index c74f01ab67..0de47f9107 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -995,6 +995,7 @@ struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create ) struct passwd *pw = NULL; char *p; fstring mapped_username; + fstring strip_username; /* we only save a copy of the username it has been mangled by winbindd use default domain */ @@ -1032,9 +1033,11 @@ struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create ) } /* setup for lookup of just the username */ - p++; - fstrcpy( mapped_username, p ); + /* remember that p and mapped_username are overlapping memory */ + p++; + fstrcpy( strip_username, p ); + fstrcpy( mapped_username, strip_username ); } /* just lookup a plain username */ diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index c4319d493a..283b2e4a89 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -786,7 +786,7 @@ int main(int argc, char **argv) { "foreground", 'F', POPT_ARG_VAL, &Fork, False, "Daemon in foreground mode" }, { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" }, { "single-daemon", 'Y', POPT_ARG_VAL, &opt_dual_daemon, False, "Single daemon mode" }, - { "no-caching", 'n', POPT_ARG_VAL, &opt_nocache, False, "Disable caching" }, + { "no-caching", 'n', POPT_ARG_VAL, &opt_nocache, True, "Disable caching" }, POPT_COMMON_SAMBA POPT_TABLEEND }; diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 74ede8621b..3bdf83cfdf 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -25,6 +25,8 @@ #include "includes.h" #include "winbindd.h" +extern BOOL opt_nocache; + #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -1028,7 +1030,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) /* Treat the info3 cache as authoritative as the lookup_usergroups() function may return cached data. */ - if ((info3 = netsamlogon_cache_get(mem_ctx, &user_sid))) { + if ( !opt_nocache && (info3 = netsamlogon_cache_get(mem_ctx, &user_sid))) { DEBUG(10, ("winbindd_getgroups: info3 has %d groups, %d other sids\n", info3->num_groups2, info3->num_other_sids)); -- cgit From 3e326c48c9bffa8f47f35d0444efec3e5927856e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Mar 2004 21:59:20 +0000 Subject: Add function next_mb_char_size() that returns a size_t of the number of bytes in the mb character at a pointer. Will be useful in fixing check_path_syntax() to not use a "blacklist". Also re-added my (C) to reply.c. I mean, really - I've been adding code to the file for over 10 years and I recognise many of the fuctions as mine ! :-). Jeremy. (This used to be commit 5a804dbe0f3ddbd6f3fbdd6b2c5510e143607541) --- source3/lib/charcnv.c | 24 ++++++++++++++++++++++++ source3/smbd/reply.c | 1 + 2 files changed, 25 insertions(+) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index b06d869bcc..9ec6e73970 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -1313,3 +1313,27 @@ size_t align_string(const void *base_ptr, const char *p, int flags) } return 0; } + +/**************************************************************** + Calculate the size (in bytes) of the next multibyte character in + our internal character set. Note that p must be pointing to a + valid mb char, not within one. +****************************************************************/ + +size_t next_mb_char_size(const char *s) +{ + size_t i; + + if (!(*s & 0x80)) + return 1; /* ascii. */ + + for ( i = 1; i <=4; i++ ) { + smb_ucs2_t uc; + if (convert_string(CH_UNIX, CH_UCS2, s, i, &uc, 2, False) == 2) { + return i; + } + } + /* We're hosed - we don't know how big this is... */ + DEBUG(10,("next_mb_char_size: unknown size at string %s\n", s)); + return 1; +} diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 48894308d1..c470d15645 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3,6 +3,7 @@ Main SMB reply routines Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Andrew Bartlett 2001 + Copyright (C) Jeremy Allison 1992-2004. 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 -- cgit From 9a86aa2c3e6687fc6480ad3f971f79cfa71442f1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Mar 2004 02:08:27 +0000 Subject: Change check_path_syntax() to use the new next_mb_char_size() function to make it generic. Remove the mb-codepage "blacklist". Alexander, please check this fix as it reverts your blacklist changes, but I'm hoping it fixes the problem in a more generic way for all charsets. I'm not trying to trample on your (excellent!) work here, just make things more generic without special cases. Jeremy. (This used to be commit ca344a784da870965684e41c93ef8bfc5e86d28f) --- source3/lib/charcnv.c | 24 ++++-------------------- source3/smbd/reply.c | 36 +++++++++++++----------------------- 2 files changed, 17 insertions(+), 43 deletions(-) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 9ec6e73970..ad15788b84 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -41,15 +41,6 @@ static smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS]; static BOOL conv_silent; /* Should we do a debug if the conversion fails ? */ -/* Unsafe unix charsets which could contain '\\' as second byte of mb character */ -static const char *conv_unsafe_charsets[] = { - "CP932", - "EUC-JP", - NULL}; -/* Global variable which is set to True in init_iconv() if unix charset is unsafe - w.r.t. '\\' in second byte of mb character. Otherwise it is set to False. -*/ -BOOL is_unix_charset_unsafe; /** * Return the name of a charset to give to iconv(). @@ -114,7 +105,6 @@ void init_iconv(void) { int c1, c2; BOOL did_reload = False; - const char **unsafe_charset = conv_unsafe_charsets; /* so that charset_name() works we need to get the UNIX<->UCS2 going first */ @@ -156,16 +146,6 @@ void init_iconv(void) init_valid_table(); conv_silent = False; } - - while(*unsafe_charset && strcmp(*unsafe_charset, conv_handles[CH_UCS2][CH_UNIX]->to_name)) { - unsafe_charset++; - } - - if (*unsafe_charset) { - is_unix_charset_unsafe = True; - } else { - is_unix_charset_unsafe = False; - } } /** @@ -1330,6 +1310,10 @@ size_t next_mb_char_size(const char *s) for ( i = 1; i <=4; i++ ) { smb_ucs2_t uc; if (convert_string(CH_UNIX, CH_UCS2, s, i, &uc, 2, False) == 2) { +#if 0 /* JRATEST */ + DEBUG(10,("next_mb_char_size: size %u at string %s\n", + (unsigned int)i, s)); +#endif return i; } } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c470d15645..0fe73cddc2 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -34,7 +34,6 @@ extern char magic_char; extern BOOL case_sensitive; extern BOOL case_preserve; extern BOOL short_case_preserve; -extern BOOL is_unix_charset_unsafe; extern int global_oplock_break; unsigned int smb_echo_count = 0; @@ -88,6 +87,8 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname) return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; } /* Go back one level... */ + /* We know this is safe as '/' cannot be part of a mb sequence. */ + /* NOTE - if this assumption is invalid we are not in good shape... */ while (d > destname) { if (*d == '/') break; @@ -112,31 +113,20 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname) } s++; } else { - /* Activate this codepath only if we know that Unix charset may contain unsafe '\\' */ - if ((is_unix_charset_unsafe == True) && ((*s & 0x80) && IS_DIRECTORY_SEP(s[1]))) { - /* - * Potential mb char with second char a directory separator. - * All the encodings we care about are 2 byte only, so do a - * conversion to unicode. If the one byte char converts then - * it really is a directory separator following. Otherwise if - * the two byte character converts (and it should or our assumption - * about character sets is broken and we return an error) then copy both - * bytes as it's a MB character, not a directory separator. - */ - - uint16 ucs2_val; - - if (convert_string(CH_UNIX, CH_UCS2, s, 1, &ucs2_val, 2, False) == 2) { - ; - } else if (convert_string(CH_UNIX, CH_UCS2, s, 2, &ucs2_val, 2, False) == 2) { + switch(next_mb_char_size(s)) { + case 4: *d++ = *s++; - } else { - DEBUG(0,("check_path_syntax: directory separator assumptions invalid !\n")); + case 3: + *d++ = *s++; + case 2: + *d++ = *s++; + case 1: + *d++ = *s++; + break; + default: + DEBUG(0,("check_path_syntax: character length assumptions invalid !\n")); return NT_STATUS_INVALID_PARAMETER; - } } - /* Just copy the char (or the second byte of the mb char). */ - *d++ = *s++; } } *d = '\0'; -- cgit From 2b7f6b1f8357b726e1b26e049149c8a7ae141911 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 17 Mar 2004 17:13:36 +0000 Subject: BUG 758 -- patch from jpeach@sgi.com (James Peach); fix pdma build (This used to be commit 77bf9fe0ce67b0a74dc5e6837c00e54884cc39ef) --- pcp/Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pcp/Makefile b/pcp/Makefile index e01731b256..e4b5fb7506 100644 --- a/pcp/Makefile +++ b/pcp/Makefile @@ -47,7 +47,9 @@ CFLAGS = $(DEBUG) LDOPTS = LDLIBS = -lpcp_pmda -lpcp DSOOPTS = -shared -LDIRT = metrics.h so_locations *.log help.dir help.pag *.pmda_$(IAM).so +LDIRT = profile.h metrics.h so_locations *.log help.dir help.pag *.pmda_$(IAM).so + +PROFILEHEADER = ../source/include/smbprofile.h INSTALL = install CC = cc @@ -65,5 +67,8 @@ $(LIBTARGET): profile.h metrics.h $(CFILES) metrics.h: profile.h mkheader.pl ./mkheader.pl +profile.h: $(PROFILEHEADER) + ln -s $(PROFILEHEADER) $@ + clobber clean: rm -f $(LDIRT) $(TARGETS) -- cgit From f6984bd0731d78a9777b54626ebd502480577878 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 17 Mar 2004 17:39:00 +0000 Subject: asu/syntax/pc_netlink doesn't fill in the pipe name in the rpc_bind response so dont check for it (This used to be commit 234800eeb61f4874e1d178aa0d901eeb360fea2f) --- source3/rpc_client/cli_pipe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b9511ae00f..72546947e4 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1223,6 +1223,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC { int i = 0; +# if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */ if ( hdr_ba->addr.len <= 0) return False; @@ -1240,6 +1241,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str)); return False; } +#endif /* JERRY */ /* check the transfer syntax */ if ((hdr_ba->transfer.version != transfer->version) || -- cgit From 8868cf6a833d114f40a5e69f2dc4f94399c05b95 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Mar 2004 19:23:44 +0000 Subject: Remove excess logging when probing for the length of the next mb char. Jeremy. (This used to be commit 5a2fd8e76587a572cdb97fa87a99cda3e450ce0e) --- source3/lib/charcnv.c | 3 +++ source3/smbd/reply.c | 30 +++++++++++++++++------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index ad15788b84..f6028bb134 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -1307,6 +1307,7 @@ size_t next_mb_char_size(const char *s) if (!(*s & 0x80)) return 1; /* ascii. */ + conv_silent = True; for ( i = 1; i <=4; i++ ) { smb_ucs2_t uc; if (convert_string(CH_UNIX, CH_UCS2, s, i, &uc, 2, False) == 2) { @@ -1314,10 +1315,12 @@ size_t next_mb_char_size(const char *s) DEBUG(10,("next_mb_char_size: size %u at string %s\n", (unsigned int)i, s)); #endif + conv_silent = False; return i; } } /* We're hosed - we don't know how big this is... */ DEBUG(10,("next_mb_char_size: unknown size at string %s\n", s)); + conv_silent = False; return 1; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 0fe73cddc2..f5c4f25e40 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -113,19 +113,23 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname) } s++; } else { - switch(next_mb_char_size(s)) { - case 4: - *d++ = *s++; - case 3: - *d++ = *s++; - case 2: - *d++ = *s++; - case 1: - *d++ = *s++; - break; - default: - DEBUG(0,("check_path_syntax: character length assumptions invalid !\n")); - return NT_STATUS_INVALID_PARAMETER; + if (!(*s & 0x80)) { + *d++ = *s++; + } else { + switch(next_mb_char_size(s)) { + case 4: + *d++ = *s++; + case 3: + *d++ = *s++; + case 2: + *d++ = *s++; + case 1: + *d++ = *s++; + break; + default: + DEBUG(0,("check_path_syntax: character length assumptions invalid !\n")); + return NT_STATUS_INVALID_PARAMETER; + } } } } -- cgit From 0eccc18d0c1b02b1b71a0c8d72a0c8833279c60f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Mar 2004 02:17:20 +0000 Subject: Added a varient of Volker's patch to fix the "self-referrals as anonymous user" problem. Jeremy. (This used to be commit 9305cd4f2d8c2c18daaa197f1513da1c3d3ee7c1) --- source3/msdfs/msdfs.c | 68 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/source3/msdfs/msdfs.c b/source3/msdfs/msdfs.c index b77e2111bc..2df5fcf4f5 100644 --- a/source3/msdfs/msdfs.c +++ b/source3/msdfs/msdfs.c @@ -151,10 +151,8 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path) if (vfs_ChDir(conn,conn->connectpath) != 0) { DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. Error was %s\n", conn->connectpath, strerror(errno) )); -#if 0 /* JRATEST ? */ talloc_destroy( conn->mem_ctx ); return False; -#endif } return True; } @@ -406,13 +404,41 @@ BOOL dfs_redirect(pstring pathname, connection_struct* conn, /* never reached */ } +/********************************************************************** + Return a self referral. +**********************************************************************/ + +static BOOL self_ref(char *pathname, struct junction_map *jucn, + int *consumedcntp, BOOL *self_referralp) +{ + struct referral *ref; + + if (self_referralp != NULL) + *self_referralp = True; + + jucn->referral_count = 1; + if((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) { + DEBUG(0,("self_ref: malloc failed for referral\n")); + return False; + } + + pstrcpy(ref->alternate_path,pathname); + ref->proximity = 0; + ref->ttl = REFERRAL_TTL; + jucn->referral_list = ref; + if (consumedcntp) + *consumedcntp = strlen(pathname); + + return True; +} + /********************************************************************** Gets valid referrals for a dfs path and fills up the junction_map structure - **********************************************************************/ +**********************************************************************/ -BOOL get_referred_path(char *pathname, struct junction_map* jucn, - int* consumedcntp, BOOL* self_referralp) +BOOL get_referred_path(char *pathname, struct junction_map *jucn, + int *consumedcntp, BOOL *self_referralp) { struct dfs_path dp; @@ -421,12 +447,13 @@ BOOL get_referred_path(char *pathname, struct junction_map* jucn, pstring conn_path; int snum; BOOL ret = False; - BOOL self_referral = False; if (!pathname || !jucn) return False; + ZERO_STRUCT(conns); + if (self_referralp) *self_referralp = False; else @@ -453,7 +480,18 @@ BOOL get_referred_path(char *pathname, struct junction_map* jucn, if ((snum = find_service(jucn->service_name)) < 0) return False; } - + + /* + * Self referrals are tested with a anonymous IPC connection and + * a GET_DFS_REFERRAL call to \\server\share. (which means dp.reqpath[0] points + * to an empty string). create_conn_struct cd's into the directory and will + * fail if it cannot (as the anonymous user). Cope with this. + */ + + if (dp.reqpath[0] == '\0') { + return self_ref(pathname, jucn, consumedcntp, self_referralp); + } + pstrcpy(conn_path, lp_pathname(snum)); if (!create_conn_struct(conn, snum, conn_path)) return False; @@ -496,24 +534,16 @@ BOOL get_referred_path(char *pathname, struct junction_map* jucn, /* if self_referral, fill up the junction map */ if (*self_referralp) { - struct referral* ref; - jucn->referral_count = 1; - if((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) { - DEBUG(0,("malloc failed for referral\n")); + if (self_ref(pathname, jucn, consumedcntp, self_referralp) == False) { goto out; } - - pstrcpy(ref->alternate_path,pathname); - ref->proximity = 0; - ref->ttl = REFERRAL_TTL; - jucn->referral_list = ref; - if (consumedcntp) - *consumedcntp = strlen(pathname); } ret = True; + out: - talloc_destroy( conn->mem_ctx ); + if (conn->mem_ctx) + talloc_destroy( conn->mem_ctx ); return ret; } -- cgit From 38cbf8f61ca8c57efc6f1a97e7f145f0103fdced Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 18 Mar 2004 07:33:26 +0000 Subject: Two little annoyances: net rpc did not inform you if no smbd is running. I never liked the error message (!) Success! when we established a trust. Volker (This used to be commit 1f2dd3a4559a6ba043fcfecb069d41f40656cc7d) --- source3/utils/net.c | 3 +-- source3/utils/net_rpc.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/source3/utils/net.c b/source3/utils/net.c index fcc8b4abe1..e4484488b6 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -150,8 +150,7 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip, if (NT_STATUS_IS_OK(nt_status)) { return nt_status; } else { - DEBUG(1,("Cannot connect to server. Error was %s\n", - nt_errstr(nt_status))); + d_printf("Could not connect to server %s\n", server_name); /* Display a nicer message depending on the result */ diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 46835d080d..afb94a616a 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -2915,7 +2915,7 @@ static int rpc_trustdom_establish(int argc, const char **argv) talloc_destroy(mem_ctx); - DEBUG(0, ("Success!\n")); + d_printf("Trust to domain %s established\n", domain_name); return 0; } -- cgit From ef8eae0688a8c9da20c187b9d5cd6a1e4f425142 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 18 Mar 2004 07:37:39 +0000 Subject: Fix sambaUserWorkstations for network samlogons against us as DC. Strip the \\ off the workstation. Volker (This used to be commit a409dd55e857e692a90124bf46575752935cc78b) --- source3/rpc_server/srv_netlog_nt.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 2f301a794c..51ed79980c 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -598,14 +598,22 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * switch (ctr->switch_value) { case NET_LOGON_TYPE: { + const char *wksname = nt_workstation; + if (!NT_STATUS_IS_OK(status = make_auth_context_fixed(&auth_context, ctr->auth.id2.lm_chal))) { return status; } + /* For a network logon, the workstation name comes in with two + * backslashes in the front. Strip them if they are there. */ + + if (*wksname == '\\') wksname++; + if (*wksname == '\\') wksname++; + /* Standard challenge/response authenticaion */ if (!make_user_info_netlogon_network(&user_info, nt_username, nt_domain, - nt_workstation, + wksname, ctr->auth.id2.lm_chal_resp.buffer, ctr->auth.id2.lm_chal_resp.str_str_len, ctr->auth.id2.nt_chal_resp.buffer, -- cgit From a650789626f7a546367bf950385bfb3ddb2911ff Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 18 Mar 2004 17:11:52 +0000 Subject: Commit Derrell Lipman's changes and fixes to libsmbclient. The build but I have not tested them beyond building. I did fix the two instances of safe_strxxx that were introduced. (This used to be commit bf89adbcb4c77792004e4ea9da248b71b72b7dbb) --- source3/lib/util_sock.c | 2 +- source3/libsmb/cliconnect.c | 87 +++++-- source3/libsmb/clientgen.c | 10 + source3/libsmb/libsmb_cache.c | 9 +- source3/libsmb/libsmbclient.c | 557 +++++++++++++++++++++++++++++++++++------- source3/rpc_client/cli_pipe.c | 2 +- 6 files changed, 548 insertions(+), 119 deletions(-) diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 15ce883b09..845aaa4b13 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -714,7 +714,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) /* create a socket to write to */ res = socket(PF_INET, type, 0); if (res == -1) { - DEBUG(0,("socket error\n")); + DEBUG(0,("socket error (%s)\n", strerror(errno))); return -1; } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b5993cd1e6..938d6fd29b 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1595,8 +1595,66 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, return NULL; } -/* Return the IP address and workgroup of a master browser on the - network. */ +/* + * Given the IP address of a master browser on the network, return its + * workgroup and connect to it. + * + * This function is provided to allow additional processing beyond what + * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master + * browsers and obtain each master browsers' list of domains (in case the + * first master browser is recently on the network and has not yet + * synchronized with other master browsers and therefore does not yet have the + * entire network browse list) + */ + +struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring workgroup, struct user_auth_info *user_info) +{ + static fstring name; + struct cli_state *cli; + struct in_addr server_ip; + + DEBUG(99, ("Looking up name of master browser %s\n", + inet_ntoa(mb_ip->ip))); + + /* + * Do a name status query to find out the name of the master browser. + * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain + * master browser will not respond to a wildcard query (or, at least, + * an NT4 server acting as the domain master browser will not). + * + * We might be able to use ONLY the query on MSBROWSE, but that's not + * yet been tested with all Windows versions, so until it is, leave + * the original wildcard query as the first choice and fall back to + * MSBROWSE if the wildcard query fails. + */ + if (!name_status_find("*", 0, 0x1d, mb_ip->ip, name) && + !name_status_find(MSBROWSE, 1, 0x1d, mb_ip->ip, name)) { + + DEBUG(99, ("Could not retrieve name status for %s\n", + inet_ntoa(mb_ip->ip))); + return NULL; + } + + if (!find_master_ip(name, &server_ip)) { + DEBUG(99, ("Could not find master ip for %s\n", name)); + return NULL; + } + + pstrcpy(workgroup, name); + + DEBUG(4, ("found master browser %s, %s\n", + name, inet_ntoa(mb_ip->ip))); + + cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info); + + return cli; + +} + +/* + * Return the IP address and workgroup of a master browser on the network, and + * connect to it. + */ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info) { @@ -1605,32 +1663,21 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user int i, count; struct in_addr server_ip; + DEBUG(99, ("Do broadcast lookup for workgroups on local network\n")); + /* Go looking for workgroups by broadcasting on the local network */ if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { + DEBUG(99, ("No master browsers responded\n")); return False; } for (i = 0; i < count; i++) { - static fstring name; - - if (!name_status_find("*", 0, 0x1d, ip_list[i].ip, name)) - continue; + DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip))); - if (!find_master_ip(name, &server_ip)) - continue; - - pstrcpy(workgroup, name); - - DEBUG(4, ("found master browser %s, %s\n", - name, inet_ntoa(ip_list[i].ip))); - - cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info); - - if (!cli) - continue; - - return cli; + cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info); + if (cli) + return(cli); } return NULL; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 20a0483881..28da73894f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -367,6 +367,16 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) void cli_close_connection(struct cli_state *cli) { + /* + * tell our peer to free his resources. Wihtout this, when an + * application attempts to do a graceful shutdown and calls + * smbc_free_context() to clean up all connections, some connections + * can remain active on the peer end, until some (long) timeout period + * later. This tree disconnect forces the peer to clean up, since the + * connection will be going away. + */ + cli_tdis(cli); + cli_nt_session_close(cli); cli_nt_netlogon_netsec_session_close(cli); diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 67dc686b48..cb40b4aaa6 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -159,10 +159,15 @@ static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) */ static int smbc_purge_cached(SMBCCTX * context) { - struct smbc_server_cache * srv = NULL; + struct smbc_server_cache * srv; + struct smbc_server_cache * next; int could_not_purge_all = 0; - for (srv=((struct smbc_server_cache *) context->server_cache);srv;srv=srv->next) { + for (srv = ((struct smbc_server_cache *) context->server_cache), + next = (srv ? srv->next :NULL); + srv; + srv = next, next = (srv ? srv->next : NULL)) { + if (smbc_remove_unused_server(context, srv->server)) { /* could not be removed */ could_not_purge_all = 1; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 35e8a9786b..68bb6661eb 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -156,18 +156,63 @@ decode_urlpart(char *segment, size_t sizeof_segment) /* * Function to parse a path and turn it into components * - * We accept smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]] - * - * smb:// means show all the workgroups - * smb://name/ means, if name<1D> or name<1B> exists, list servers in workgroup, - * else, if name<20> exists, list all shares for server ... + * The general format of an SMB URI is explain in Christopher Hertel's CIFS + * book, at http://ubiqx.org/cifs/Appendix-D.html. We accept a subset of the + * general format ("smb:" only; we do not look for "cifs:"), and expand on + * what he calls "context", herein called "options" to avoid conflict with the + * SMBCCTX context used throughout this library. We add the "mb" keyword + * which applies as follows: + * + * + * We accept: + * smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]][?options] + * + * Meaning of URLs: + * + * smb:// show all workgroups known by the first master browser found + * smb://?mb=.any same as smb:// (i.e. without any options) + * + * smb://?mb=.all show all workgroups known by every master browser found. + * Why might you want this? In an "appliance" application + * where the workgroup/domain being used on the local network + * is not known ahead of time, but where one wanted to + * provide network services via samba, a unique workgroup + * could be used. However, when the appliance is first + * started, the local samba instance's master browser has not + * synchronized with the other master browser(s) on the + * network (and might not synchronize for 12 minutes) and + * therefore is not aware of the workgroup/ domain names + * available on the network. This option may be used to + * overcome the problem of a libsmbclient application + * arbitrarily selecting the local (still ignorant) master + * browser to obtain its list of workgroups/domains and + * getting back a practically emmpty list. By requesting + * the list of workgroups/domains from each found master + * browser on the local network, a complete list of + * workgroups/domains can be built. + * + * smb://?mb=name NOT YET IMPLEMENTED -- show all workgroups known by the + * master browser whose name is "name" + * + * smb://name/ if name<1D> or name<1B> exists, list servers in + * workgroup, else, if name<20> exists, list all shares + * for server ... + * + * If "options" are provided, this function returns the entire option list as + * a string, for later parsing by the caller. */ static const char *smbc_prefix = "smb:"; static int -smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, char *path, - char *user, char *password) /* FIXME, lengths of strings */ +smbc_parse_path(SMBCCTX *context, + const char *fname, + char *server, int server_len, + char *share, int share_len, + char *path, int path_len, + char *user, int user_len, + char *password, int password_len, + char *options, int options_len) { static pstring s; pstring userinfo; @@ -176,10 +221,11 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, int len; server[0] = share[0] = path[0] = user[0] = password[0] = (char)0; + if (options != NULL && options_len > 0) { + options[0] = (char)0; + } pstrcpy(s, fname); - /* clean_fname(s); causing problems ... */ - /* see if it has the right prefix */ len = strlen(smbc_prefix); if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) { @@ -192,11 +238,25 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { + DEBUG(1, ("Invalid path (does not begin with smb://")); return -1; } - p += 2; /* Skip the // or \\ */ + p += 2; /* Skip the double slash */ + + /* See if any options were specified */ + if (q = strrchr(p, '?')) { + /* There are options. Null terminate here and point to them */ + *q++ = '\0'; + + DEBUG(4, ("Found options '%s'", q)); + + /* Copy the options */ + if (options != NULL && options_len > 0) { + safe_strcpy(options, q, options_len - 1); + } + } if (*p == (char)0) goto decoding; @@ -247,10 +307,10 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, } if (username[0]) - strncpy(user, username, sizeof(fstring)); /* FIXME, size and domain */ + strncpy(user, username, user_len); /* FIXME, domain */ if (passwd[0]) - strncpy(password, passwd, sizeof(fstring)); /* FIXME, size */ + strncpy(password, passwd, password_len); } @@ -268,24 +328,57 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, } - pstrcpy(path, p); + safe_strcpy(path, p, path_len - 1); all_string_sub(path, "/", "\\", 0); decoding: - decode_urlpart(path, sizeof(pstring)); - decode_urlpart(server, sizeof(fstring)); - decode_urlpart(share, sizeof(fstring)); - decode_urlpart(user, sizeof(fstring)); - decode_urlpart(password, sizeof(fstring)); + decode_urlpart(path, path_len); + decode_urlpart(server, server_len); + decode_urlpart(share, share_len); + decode_urlpart(user, user_len); + decode_urlpart(password, password_len); return 0; } /* - * Convert an SMB error into a UNIX error ... + * Verify that the options specified in a URL are valid */ +static int smbc_check_options(char *server, char *share, char *path, char *options) +{ + DEBUG(4, ("smbc_check_options(): server='%s' share='%s' path='%s' options='%s'\n", server, share, path, options)); + + /* No options at all is always ok */ + if (! *options) return 0; + + /* + * For right now, we only support a very few options possibilities. + * No options are supported if server, share, or path are not empty. + * If all are empty, then we support the following two choices right + * now: + * + * mb=.any + * mb=.all + */ + if ((*server || *share || *path) && *options) { + /* Invalid: options provided with server, share, or path */ + DEBUG(1, ("Found unsupported options (%s) with non-empty server, share, or path\n", options)); + return -1; + } + + if (strcmp(options, "mb=.any") != 0 && + strcmp(options, "mb=.all") != 0) { + DEBUG(1, ("Found unsupported options (%s)\n", options)); + return -1; + } + return 0; +} + +/* + * Convert an SMB error into a UNIX error ... + */ static int smbc_errno(SMBCCTX *context, struct cli_state *c) { int ret = cli_errno(c); @@ -469,6 +562,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); +#if 0 /* djl: obsolete code? neither group nor p is used beyond here */ if ((p=strchr_m(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { @@ -477,6 +571,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, *p = 0; } +#endif DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); @@ -503,7 +598,6 @@ SMBCSRV *smbc_server(SMBCCTX *context, */ c.port = 445; if (!cli_connect(&c, server_n, &ip)) { - cli_shutdown(&c); errno = ENETUNREACH; return NULL; } @@ -598,6 +692,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, DEBUG(2, ("Server connect ok: //%s/%s: %p\n", server, share, srv)); + DLIST_ADD(context->internal->_servers, srv); return srv; failed: @@ -648,17 +743,16 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, password, 0, Undefined, NULL); if (! NT_STATUS_IS_OK(nt_status)) { - DEBUG(0,("cli_full_connection failed! (%s)\n", + DEBUG(1,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); errno = ENOTSUP; return NULL; } if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) { - DEBUG(0, ("cli_nt_session_open fail! (%s)\n", - nt_errstr(nt_status))); + DEBUG(1, ("cli_nt_session_open fail!\n")); errno = ENOTSUP; - free(ipc_cli); + cli_shutdown(ipc_cli); return NULL; } @@ -673,14 +767,14 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, if (!NT_STATUS_IS_OK(nt_status)) { errno = smbc_errno(context, ipc_cli); - free(ipc_cli); + cli_shutdown(ipc_cli); return NULL; } ipc_srv = (SMBCSRV *)malloc(sizeof(*ipc_srv)); if (!ipc_srv) { errno = ENOMEM; - free(ipc_cli); + cli_shutdown(ipc_cli); return NULL; } @@ -690,14 +784,23 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, free(ipc_cli); /* now add it to the cache (internal or external) */ + + errno = 0; /* let cache function set errno if it likes */ if (context->callbacks.add_cached_srv_fn(context, ipc_srv, server, "IPC$$", workgroup, username)) { DEBUG(3, (" Failed to add server to cache\n")); + if (errno == 0) { + errno = ENOMEM; + } + cli_shutdown(&ipc_srv->cli); + free(ipc_srv); return NULL; } + + DLIST_ADD(context->internal->_servers, ipc_srv); } return ipc_srv; @@ -730,7 +833,16 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m } - smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return NULL; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -1042,7 +1154,16 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) } - smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -1141,11 +1262,23 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - smbc_parse_path(ocontext, oname, server1, share1, path1, user1, password1); + smbc_parse_path(ocontext, oname, + server1, sizeof(server1), + share1, sizeof(share1), + path1, sizeof(path1), + user1, sizeof(user1), + password1, sizeof(password1), + NULL, 0); if (user1[0] == (char)0) fstrcpy(user1, ocontext->user); - smbc_parse_path(ncontext, nname, server2, share2, path2, user2, password2); + smbc_parse_path(ncontext, nname, + server2, sizeof(server2), + share2, sizeof(share2), + path2, sizeof(path2), + user2, sizeof(user2), + password2, sizeof(password2), + NULL, 0); if (user2[0] == (char)0) fstrcpy(user2, ncontext->user); @@ -1348,7 +1481,16 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) DEBUG(4, ("smbc_stat(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -1360,27 +1502,6 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) return -1; /* errno set by smbc_server */ } - /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { - - mode = aDIR | aRONLY; - - } - else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - - if (strcmp(path, "\\") == 0) { - - mode = aDIR | aRONLY; - - } - else { - - mode = aRONLY; - smbc_stat_printjob(srv, path, &size, &m_time); - c_time = a_time = m_time; - - } - else { */ - if (!smbc_getatr(context, srv, path, &mode, &size, &c_time, &a_time, &m_time, &ino)) { @@ -1462,16 +1583,7 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) /* * Routine to open a directory - * - * We want to allow: - * - * smb: which should list all the workgroups available - * smb:workgroup - * smb:workgroup//server - * smb://server - * smb://server/share - * smb:// which should list shares on server - * smb:///share which should list files on share + * We accept the URL syntax explained in smbc_parse_path(), above. */ static void smbc_remove_dir(SMBCFILE *dir) @@ -1536,7 +1648,6 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint ZERO_STRUCTP(dir->dir_list); dir->dir_end = dir->dir_next = dir->dir_list; - } else { @@ -1552,7 +1663,6 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint ZERO_STRUCTP(dir->dir_end->next); dir->dir_end = dir->dir_end->next; - } dir->dir_end->next = NULL; @@ -1575,6 +1685,46 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint } +static void +list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *state) +{ + SMBCFILE *dir = (SMBCFILE *)state; + struct smbc_dir_list *dir_list; + struct smbc_dirent *dirent; + int dirent_type; + int remove = 0; + + dirent_type = dir->dir_type; + + if (add_dirent(dir, name, comment, dirent_type) < 0) { + + /* An error occurred, what do we do? */ + /* FIXME: Add some code here */ + } + + /* Point to the one just added */ + dirent = dir->dir_end->dirent; + + /* See if this was a duplicate */ + for (dir_list = dir->dir_list; + dir_list != dir->dir_end; + dir_list = dir_list->next) { + if (! remove && + strcmp(dir_list->dirent->name, dirent->name) == 0) { + /* Duplicate. End end of list need to be removed. */ + remove = 1; + } + + if (remove && dir_list->next == dir->dir_end) { + /* Found the end of the list. Remove it. */ + dir->dir_end = dir_list; + free(dir_list->next); + dir_list->next = NULL; + break; + } + } +} + static void list_fn(const char *name, uint32 type, const char *comment, void *state) { @@ -1615,7 +1765,6 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) /* FIXME: Add some code here */ } - } static void @@ -1635,7 +1784,7 @@ dir_list_fn(file_info *finfo, const char *mask, void *state) static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) { - fstring server, share, user, password; + fstring server, share, user, password, options; pstring workgroup; pstring path; SMBCSRV *srv = NULL; @@ -1656,13 +1805,26 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - if (smbc_parse_path(context, fname, server, share, path, user, password)) { + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(path), + password, sizeof(password), + options, sizeof(options))) { DEBUG(4, ("no valid path\n")); errno = EINVAL; return NULL; } - DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' path='%s'\n", fname, server, share, path)); + DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' path='%s' options='%s'\n", fname, server, share, path, options)); + + /* Ensure the options are valid */ + if (smbc_check_options(server, share, path, options)) { + DEBUG(4, ("unacceptable options (%s)\n", options)); + errno = EINVAL; + return NULL; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -1686,8 +1848,9 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) dir->file = False; dir->dir_list = dir->dir_next = dir->dir_end = NULL; - if (server[0] == (char)0) { - struct in_addr server_ip; + if (server[0] == (char)0 && + (! *options || strcmp(options, "mb=.any") == 0)) { + struct in_addr server_ip; if (share[0] != (char)0 || path[0] != (char)0) { errno = EINVAL; @@ -1698,9 +1861,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - /* We have server and share and path empty ... so list the workgroups */ - /* first try to get the LMB for our workgroup, and if that fails, */ - /* try the DMB */ + /* + * We have server and share and path empty ... so list the + * workgroups first try to get the LMB for our workgroup, and + * if that fails, try the DMB + */ pstrcpy(workgroup, lp_workgroup()); @@ -1726,7 +1891,21 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) cli_shutdown(cli); } else { - if (!name_status_find("*", 0, 0, server_ip, server)) { + /* + * Do a name status query to find out the name of the + * master browser. We use <01><02>__MSBROWSE__<02>#01 if + * *#00 fails because a domain master browser will not + * respond to a wildcard query (or, at least, an NT4 + * server acting as the domain master browser will not). + * + * We might be able to use ONLY the query on MSBROWSE, but + * that's not yet been tested with all Windows versions, + * so until it is, leave the original wildcard query as + * the first choice and fall back to MSBROWSE if the + * wildcard query fails. + */ + if (!name_status_find("*", 0, 0x1d, server_ip, server) && + !name_status_find(MSBROWSE, 1, 0x1d, server_ip, server)) { errno = ENOENT; return NULL; } @@ -1734,9 +1913,10 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); - /* - * Get a connection to IPC$ on the server if we do not already have one - */ + /* + * Get a connection to IPC$ on the server if we do not already + * have one + */ srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { @@ -1756,6 +1936,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_fn, (void *)dir)) { + DEBUG(1, ("Could not enumerate domains using '%s'\n", workgroup)); if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -1765,9 +1946,99 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - } - else { /* Server not an empty string ... Check the rest and see what gives */ + } else if (server[0] == (char)0 && + (! *options || strcmp(options, "mb=.all") == 0)) { + + int i; + int count; + struct ip_service *ip_list; + struct ip_service server_addr; + struct user_auth_info u_info; + struct cli_state *cli; + + if (share[0] != (char)0 || path[0] != (char)0) { + + errno = EINVAL; + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + return NULL; + } + + pstrcpy(u_info.username, user); + pstrcpy(u_info.password, password); + + /* + * We have server and share and path empty but options + * requesting that we scan all master browsers for their list + * of workgroups/domains. This implies that we must first try + * broadcast queries to find all master browsers, and if that + * doesn't work, then try our other methods which return only + * a single master browser. + */ + + if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { + if (!find_master_ip(workgroup, &server_addr.ip)) { + + errno = ENOENT; + return NULL; + } + ip_list = &server_addr; + count = 1; + } + + for (i = 0; i < count; i++) { + DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip))); + + cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info); + fstrcpy(server, cli->desthost); + cli_shutdown(cli); + + DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); + + /* + * For each returned master browser IP address, get a + * connection to IPC$ on the server if we do not + * already have one, and determine the + * workgroups/domains that it knows about. + */ + + srv = smbc_server(context, server, + "IPC$", workgroup, user, password); + if (!srv) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + return NULL; + } + + dir->srv = srv; + dir->dir_type = SMBC_WORKGROUP; + + /* Now, list the stuff ... */ + + if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn, + (void *)dir)) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + errno = cli_errno(&srv->cli); + + return NULL; + + } + } + } else { + /* + * Server not an empty string ... Check the rest and see what + * gives + */ if (share[0] == (char)0) { if (path[0] != (char)0) { /* Should not have empty share with path */ @@ -1796,7 +2067,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) */ - if (!name_status_find("*", 0, 0, rem_ip, buserver)) { + if (!name_status_find(server, 0, 0, rem_ip, buserver)) { DEBUG(0, ("Could not get name of local/domain master browser for server %s\n", server)); errno = EPERM; /* FIXME, is this correct */ @@ -1835,7 +2106,6 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - } else { @@ -1962,7 +2232,6 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) SAFE_FREE(dir->fname); SAFE_FREE(dir); /* Free the space too */ - } return 0; @@ -1983,6 +2252,7 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) !context->internal->_initialized) { errno = EINVAL; + DEBUG(0, ("Invalid context in smbc_readdir_ctx()\n")); return NULL; } @@ -1990,6 +2260,7 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; + DEBUG(0, ("Invalid dir in smbc_readdir_ctx()\n")); return NULL; } @@ -1997,16 +2268,17 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; + DEBUG(0, ("Found file vs directory in smbc_readdir_ctx()\n")); return NULL; } - if (!dir->dir_next) + if (!dir->dir_next) { return NULL; + } else { dirent = dir->dir_next->dirent; - if (!dirent) { errno = ENOENT; @@ -2142,7 +2414,16 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -2229,7 +2510,17 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) + { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -2466,7 +2757,16 @@ int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode) DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -2518,7 +2818,16 @@ int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) DEBUG(4, ("smbc_utimes(%s, [%s])\n", fname, ctime(&t))); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3353,7 +3662,16 @@ int smbc_setxattr_ctx(SMBCCTX *context, DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", fname, name, (int) size, (char *) value)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3485,7 +3803,16 @@ int smbc_getxattr_ctx(SMBCCTX *context, DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3568,7 +3895,16 @@ int smbc_removexattr_ctx(SMBCCTX *context, DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3700,7 +4036,16 @@ static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return NULL; + } /* What if the path is empty, or the file exists? */ @@ -3814,7 +4159,16 @@ static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_li DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3867,7 +4221,16 @@ static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3989,13 +4352,17 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) /* First try to remove the servers the nice way. */ if (context->callbacks.purge_cached_fn(context)) { SMBCSRV * s; + SMBCSRV * next; DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n")); s = context->internal->_servers; while (s) { + DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", s, s->cli.fd)); cli_shutdown(&s->cli); context->callbacks.remove_cached_srv_fn(context, s); + next = s->next; + DLIST_REMOVE(context->internal->_servers, s); SAFE_FREE(s); - s = s->next; + s = next; } context->internal->_servers = NULL; } diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 72546947e4..82a4b21754 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1443,7 +1443,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) cli->nt_pipe_fnum = (uint16)fnum; } else { if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, O_CREAT|O_RDWR, DENY_NONE)) == -1) { - DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n", + DEBUG(1,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n", pipe_names[pipe_idx].client_pipe, cli->desthost, cli_errstr(cli))); return False; } -- cgit From 351eb266176f6a4c204e92c206ce3791237b195a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Mar 2004 17:58:47 +0000 Subject: Correctness patch from fumiya@miraclelinux.com to count characters correctly, doesn't affect what got put on the wire. Jeremy. (This used to be commit 05243a8de06b6589e2405a4a7be25cdf5d338c10) --- source3/lib/charcnv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index f6028bb134..11b1448f1e 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -839,6 +839,9 @@ size_t push_ascii_nstring(void *dest, const char *src) smb_panic("failed to create UCS2 buffer"); } + /* We're using buffer_len below to count ucs2 characters, not bytes. */ + buffer_len /= sizeof(smb_ucs2_t); + dest_len = 0; for (i = 0; buffer[i] != 0 && (i < buffer_len); i++) { unsigned char mb[10]; -- cgit From 4b9423fc2205b6f37300e134f425d0aef3022a6e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 18 Mar 2004 18:10:30 +0000 Subject: BUG 932: ulrich@holeschak.de (Ulrich Holeschak); fix local password change using pam_smbpass (This used to be commit ad59b6fd9c822033bb8ab85ef9c51ec912fd9fd5) --- source3/pam_smbpass/pam_smb_auth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/pam_smbpass/pam_smb_auth.c b/source3/pam_smbpass/pam_smb_auth.c index f4cbb59af3..4452538d32 100644 --- a/source3/pam_smbpass/pam_smb_auth.c +++ b/source3/pam_smbpass/pam_smb_auth.c @@ -198,7 +198,7 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl, /* Add the user to the db if they aren't already there. */ if (!exist) { - retval = local_password_change( name, LOCAL_ADD_USER, + retval = local_password_change( name, LOCAL_ADD_USER|LOCAL_SET_PASSWORD, pass, err_str, sizeof(err_str), msg_str, sizeof(msg_str) ); -- cgit From 2332bebd9fabc32dbc2756347338dbecc06e527b Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 18 Mar 2004 20:05:00 +0000 Subject: merge from 3.0...LDAP password lockout support (This used to be commit b627cee3848d73e35181c9e6fdd9931452b28e48) --- source3/Makefile.in | 3 +- source3/include/passdb.h | 9 +++ source3/include/smbldap.h | 1 + source3/lib/smbldap.c | 1 + source3/passdb/login_cache.c | 174 +++++++++++++++++++++++++++++++++++++++++++ source3/passdb/pdb_ldap.c | 121 +++++++++++++++++++++++++++++- 6 files changed, 307 insertions(+), 2 deletions(-) create mode 100644 source3/passdb/login_cache.c diff --git a/source3/Makefile.in b/source3/Makefile.in index def96051b7..9b4c8d5c04 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -297,7 +297,8 @@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ passdb/util_sam_sid.o passdb/pdb_compat.o \ - passdb/privileges.o passdb/lookup_sid.o @PDB_STATIC@ passdb/pdb_sql.o + passdb/privileges.o passdb/lookup_sid.o \ + passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o XML_OBJ = passdb/pdb_xml.o MYSQL_OBJ = passdb/pdb_mysql.o diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 21feb7208f..92e4bf3e8d 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -134,6 +134,15 @@ enum pdb_value_state { #define IS_SAM_SET(x, flag) (pdb_get_init_flags(x, flag) == PDB_SET) #define IS_SAM_CHANGED(x, flag) (pdb_get_init_flags(x, flag) == PDB_CHANGED) #define IS_SAM_DEFAULT(x, flag) (pdb_get_init_flags(x, flag) == PDB_DEFAULT) + +/* cache for bad password lockout data, to be used on replicated SAMs */ +typedef struct logon_cache_struct +{ + time_t entry_timestamp; + uint16 acct_ctrl; + uint16 bad_password_count; + time_t bad_password_time; +} LOGIN_CACHE; typedef struct sam_passwd { diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 2f71f971d9..68a2c00afe 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -92,6 +92,7 @@ #define LDAP_ATTR_LOGON_COUNT 36 #define LDAP_ATTR_MUNGED_DIAL 37 #define LDAP_ATTR_BAD_PASSWORD_TIME 38 +#define LDAP_ATTR_MOD_TIMESTAMP 39 typedef struct _attrib_map_entry { int attrib; diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index c15ba51306..20c2163cde 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -100,6 +100,7 @@ ATTRIB_MAP_ENTRY attrib_map_v30[] = { { LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" }, { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" }, { LDAP_ATTR_BAD_PASSWORD_TIME, "sambaBadPasswordTime" }, + { LDAP_ATTR_MOD_TIMESTAMP, "modifyTimestamp" }, { LDAP_ATTR_LIST_END, NULL } }; diff --git a/source3/passdb/login_cache.c b/source3/passdb/login_cache.c new file mode 100644 index 0000000000..4b760172ec --- /dev/null +++ b/source3/passdb/login_cache.c @@ -0,0 +1,174 @@ +/* + Unix SMB/CIFS implementation. + SAM_ACCOUNT local cache for + Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2004. + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_PASSDB + +#define LOGIN_CACHE_FILE "login_cache.tdb" + +#define SAM_CACHE_FORMAT "dwwd" + +static TDB_CONTEXT *cache; + +BOOL login_cache_init(void) +{ + char* cache_fname = NULL; + + /* skip file open if it's already opened */ + if (cache) return True; + + asprintf(&cache_fname, "%s/%s", lp_lockdir(), LOGIN_CACHE_FILE); + if (cache_fname) + DEBUG(5, ("Opening cache file at %s\n", cache_fname)); + else { + DEBUG(0, ("Filename allocation failed.\n")); + return False; + } + + cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, + O_RDWR|O_CREAT, 0644); + + if (!cache) + DEBUG(5, ("Attempt to open %s failed.\n", cache_fname)); + + SAFE_FREE(cache_fname); + + return (cache ? True : False); +} + +BOOL login_cache_shutdown(void) +{ + /* tdb_close routine returns -1 on error */ + if (!cache) return False; + DEBUG(5, ("Closing cache file\n")); + return tdb_close(cache) != -1; +} + +/* if we can't read the cache, oh well, no need to return anything */ +LOGIN_CACHE * login_cache_read(SAM_ACCOUNT *sampass) +{ + TDB_DATA keybuf, databuf; + LOGIN_CACHE *entry; + + if (!login_cache_init()) + return NULL; + + keybuf.dptr = strdup(pdb_get_nt_username(sampass)); + if (!keybuf.dptr || !strlen(keybuf.dptr)) { + SAFE_FREE(keybuf.dptr); + return NULL; + } + keybuf.dsize = strlen(keybuf.dptr) + 1; + + DEBUG(7, ("Looking up login cache for user %s\n", + keybuf.dptr)); + databuf = tdb_fetch(cache, keybuf); + SAFE_FREE(keybuf.dptr); + + if (!(entry = malloc(sizeof(LOGIN_CACHE)))) { + DEBUG(1, ("Unable to allocate cache entry buffer!\n")); + SAFE_FREE(databuf.dptr); + return NULL; + } + + if (tdb_unpack (databuf.dptr, databuf.dsize, SAM_CACHE_FORMAT, + &entry->entry_timestamp, &entry->acct_ctrl, + &entry->bad_password_count, + &entry->bad_password_time) == -1) { + DEBUG(7, ("No cache entry found\n")); + SAFE_FREE(databuf.dptr); + return NULL; + } + + DEBUG(5, ("Found login cache entry: timestamp %12u, flags 0x%x, count %d, time %12u\n", + entry->entry_timestamp, entry->acct_ctrl, + entry->bad_password_count, entry->bad_password_time)); + return entry; +} + +BOOL login_cache_write(const SAM_ACCOUNT *sampass, LOGIN_CACHE entry) +{ + + TDB_DATA keybuf, databuf; + BOOL ret; + + + keybuf.dptr = strdup(pdb_get_nt_username(sampass)); + if (!keybuf.dptr || !strlen(keybuf.dptr)) { + SAFE_FREE(keybuf.dptr); + return False; + } + keybuf.dsize = strlen(keybuf.dptr) + 1; + + entry.entry_timestamp = time(NULL); + + databuf.dsize = + tdb_pack(NULL, 0, SAM_CACHE_FORMAT, + entry.entry_timestamp, + entry.acct_ctrl, + entry.bad_password_count, + entry.bad_password_time); + databuf.dptr = malloc(databuf.dsize); + if (!databuf.dptr) { + SAFE_FREE(keybuf.dptr); + return False; + } + + if (tdb_pack(databuf.dptr, databuf.dsize, SAM_CACHE_FORMAT, + entry.entry_timestamp, + entry.acct_ctrl, + entry.bad_password_count, + entry.bad_password_time) + != databuf.dsize) { + SAFE_FREE(keybuf.dptr); + SAFE_FREE(databuf.dptr); + return False; + } + + ret = tdb_store(cache, keybuf, databuf, 0); + SAFE_FREE(keybuf.dptr); + SAFE_FREE(databuf.dptr); + return ret == 0; +} + +BOOL login_cache_delentry(const SAM_ACCOUNT *sampass) +{ + int ret; + TDB_DATA keybuf; + + if (!login_cache_init()) + return False; + + keybuf.dptr = strdup(pdb_get_nt_username(sampass)); + if (!keybuf.dptr || !strlen(keybuf.dptr)) { + SAFE_FREE(keybuf.dptr); + return False; + } + keybuf.dsize = strlen(keybuf.dptr) + 1; + DEBUG(9, ("About to delete entry for %s\n", keybuf.dptr)); + ret = tdb_delete(cache, keybuf); + DEBUG(9, ("tdb_delete returned %d\n", ret)); + + SAFE_FREE(keybuf.dptr); + return ret == 0; +} + diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 0ebb63b3fb..b7e28a9e99 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -391,6 +391,25 @@ static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state, #endif +static time_t ldapsam_get_entry_timestamp( + struct ldapsam_privates *ldap_state, + LDAPMessage * entry) +{ + pstring temp; + struct tm tm; + + if (!smbldap_get_single_pstring( + ldap_state->smbldap_state->ldap_struct, entry, + get_userattr_key2string(ldap_state->schema_ver, + LDAP_ATTR_MOD_TIMESTAMP), + temp)) + return (time_t) 0; + + strptime(temp, "%Y%m%d%H%M%SZ", &tm); + tzset(); + return (mktime(&tm) - timezone); +} + /********************************************************************** Initialize SAM_ACCOUNT from an LDAP query. (Based on init_sam_from_buffer in pdb_tdb.c) @@ -405,7 +424,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, kickoff_time, pass_last_set_time, pass_can_change_time, - pass_must_change_time; + pass_must_change_time, + ldap_entry_time, + bad_password_time; pstring username, domain, nt_username, @@ -427,6 +448,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, uint32 hours_len; uint8 hours[MAX_HOURS_LEN]; pstring temp; + LOGIN_CACHE *cache_entry = NULL; /* * do a little initialization @@ -720,6 +742,15 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); } + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, + get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_TIME), temp)) { + /* leave as default */ + } else { + bad_password_time = (time_t) atol(temp); + pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET); + } + + if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_COUNT), temp)) { /* leave as default */ @@ -732,6 +763,43 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_hours(sampass, hours, PDB_SET); + /* check the timestamp of the cache vs ldap entry */ + if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state, + entry))) + return True; + + /* see if we have newer updates */ + if (!(cache_entry = login_cache_read(sampass))) { + DEBUG (9, ("No cache entry, bad count = %d, bad time = %d\n", + pdb_get_bad_password_count(sampass), + pdb_get_bad_password_time(sampass))); + return True; + } + + DEBUG(7, ("ldap time is %d, cache time is %d, bad time = %d\n", + ldap_entry_time, cache_entry->entry_timestamp, + cache_entry->bad_password_time)); + + if (ldap_entry_time > cache_entry->entry_timestamp) { + /* cache is older than directory , so + we need to delete the entry but allow the + fields to be written out */ + login_cache_delentry(sampass); + } else { + /* read cache in */ + pdb_set_acct_ctrl(sampass, + pdb_get_acct_ctrl(sampass) | + (cache_entry->acct_ctrl & ACB_AUTOLOCK), + PDB_SET); + pdb_set_bad_password_count(sampass, + cache_entry->bad_password_count, + PDB_SET); + pdb_set_bad_password_time(sampass, + cache_entry->bad_password_time, + PDB_SET); + } + + SAFE_FREE(cache_entry); return True; } @@ -907,6 +975,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp); + if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) { @@ -954,6 +1023,56 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN)); + /* password lockout cache: + - If we are now autolocking or clearing, we write to ldap + - If we are clearing, we delete the cache entry + - If the count is > 0, we update the cache + + This even means when autolocking, we cache, just in case the + update doesn't work, and we have to cache the autolock flag */ + + if (need_update(sampass, PDB_BAD_PASSWORD_COUNT)) /* && + need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ { + uint16 badcount = pdb_get_bad_password_count(sampass); + time_t badtime = pdb_get_bad_password_time(sampass); + uint32 pol; + account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &pol); + + DEBUG(3, ("updating bad password fields, policy=%d, count=%d, time=%d\n", pol, badcount, badtime)); + + if ((badcount >= pol) || (badcount == 0)) { + DEBUG(7, ("making mods to update ldap, count=%d, time=%d\n", badcount, badtime)); + slprintf (temp, sizeof (temp) - 1, "%li", badcount); + smbldap_make_mod( + ldap_state->smbldap_state->ldap_struct, + existing, mods, + get_userattr_key2string( + ldap_state->schema_ver, + LDAP_ATTR_BAD_PASSWORD_COUNT), + temp); + + slprintf (temp, sizeof (temp) - 1, "%li", badtime); + smbldap_make_mod( + ldap_state->smbldap_state->ldap_struct, + existing, mods, + get_userattr_key2string( + ldap_state->schema_ver, + LDAP_ATTR_BAD_PASSWORD_TIME), + temp); + } + if (badcount == 0) { + DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass))); + login_cache_delentry(sampass); + } else { + LOGIN_CACHE cache_entry ={time(NULL), + pdb_get_acct_ctrl(sampass), + badcount, badtime}; + DEBUG(7, ("Updating bad password count and time in login cache\n")); + login_cache_write(sampass, cache_entry); + } + + } + return True; } -- cgit From 00e8b6d5ce02d021d23bd6b0816504604756b825 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 18 Mar 2004 22:29:54 +0000 Subject: Apply Craig Barratt's fixes to allow multiple exlusion files and patterns. Much of this was applied by hand because of the changes in the code. However, it builds and smbclient seems to work still. The Amanda folks are testing and it seems to work there as well. (This used to be commit 10d05b57c5c66718fb1ca476f7214087ddae29ee) --- source3/client/clitar.c | 4 ++-- source3/lib/util.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/source3/client/clitar.c b/source3/client/clitar.c index f38d6fe91a..e43b3e4cc5 100644 --- a/source3/client/clitar.c +++ b/source3/client/clitar.c @@ -800,7 +800,7 @@ static void do_tar(file_info *finfo) #ifdef HAVE_REGEX_H (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) { #else - (tar_re_search && mask_match(exclaim, cliplist[0], True))) { + (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) { #endif DEBUG(3,("Skipping file %s\n", exclaim)); return; @@ -1153,7 +1153,7 @@ static void do_tarput(void) #ifdef HAVE_REGEX_H (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0))); #else - (tar_re_search && mask_match(finfo.name, cliplist[0], True))); + (tar_re_search && mask_match_list(finfo.name, cliplist, clipn, True))); #endif DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name)); diff --git a/source3/lib/util.c b/source3/lib/util.c index 3a8d627ee9..10d224baab 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2320,6 +2320,20 @@ BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive) return ms_fnmatch(pattern, string, Protocol, is_case_sensitive) == 0; } +/******************************************************************* + A wrapper that handles a list of patters and calls mask_match() + on each. Returns True if any of the patterns match. +*******************************************************************/ + +BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive) +{ + while (listLen-- > 0) { + if (mask_match(string, *list++, is_case_sensitive)) + return True; + } + return False; +} + /********************************************************* Recursive routine that is called by unix_wild_match. *********************************************************/ -- cgit From 7ff5b737d8e93ef06f40647ac4d108630d436616 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Mar 2004 01:29:18 +0000 Subject: Fix gcc warnings. Fix mkproto with new type. Jeremy. (This used to be commit 6e4123fd6bb8622063c25dd6ad003f97eda7c6f5) --- source3/passdb/pdb_ldap.c | 21 +++++++++++---------- source3/script/mkproto.awk | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index b7e28a9e99..2141f2a3f1 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -770,15 +770,15 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, /* see if we have newer updates */ if (!(cache_entry = login_cache_read(sampass))) { - DEBUG (9, ("No cache entry, bad count = %d, bad time = %d\n", - pdb_get_bad_password_count(sampass), - pdb_get_bad_password_time(sampass))); + DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n", + (unsigned int)pdb_get_bad_password_count(sampass), + (unsigned int)pdb_get_bad_password_time(sampass))); return True; } - DEBUG(7, ("ldap time is %d, cache time is %d, bad time = %d\n", - ldap_entry_time, cache_entry->entry_timestamp, - cache_entry->bad_password_time)); + DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n", + (unsigned int)ldap_entry_time, (unsigned int)cache_entry->entry_timestamp, + (unsigned int)cache_entry->bad_password_time)); if (ldap_entry_time > cache_entry->entry_timestamp) { /* cache is older than directory , so @@ -1038,11 +1038,13 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, uint32 pol; account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &pol); - DEBUG(3, ("updating bad password fields, policy=%d, count=%d, time=%d\n", pol, badcount, badtime)); + DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n", + (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime)); if ((badcount >= pol) || (badcount == 0)) { - DEBUG(7, ("making mods to update ldap, count=%d, time=%d\n", badcount, badtime)); - slprintf (temp, sizeof (temp) - 1, "%li", badcount); + DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n", + (unsigned int)badcount, (unsigned int)badtime)); + slprintf (temp, sizeof (temp) - 1, "%li", (long)badcount); smbldap_make_mod( ldap_state->smbldap_state->ldap_struct, existing, mods, @@ -1070,7 +1072,6 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, DEBUG(7, ("Updating bad password count and time in login cache\n")); login_cache_write(sampass, cache_entry); } - } return True; diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk index 3835ea3af3..b38f405e0d 100644 --- a/source3/script/mkproto.awk +++ b/source3/script/mkproto.awk @@ -132,7 +132,7 @@ END { gotstart = 1; } - if( $0 ~ /^WINBINDD_PW|^WINBINDD_GR|^NT_PRINTER_INFO_LEVEL_2/ ) { + if( $0 ~ /^WINBINDD_PW|^WINBINDD_GR|^NT_PRINTER_INFO_LEVEL_2|^LOGIN_CACHE/ ) { gotstart = 1; } -- cgit From 9915ded60a1c59528ab6485dc14ac34f19f6153f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 19 Mar 2004 11:27:14 +0000 Subject: the buffer must be greater then src string len otherwise bad things happen! (This used to be commit 83213238c2f1541a0520175abfdb1f884e06a018) --- source3/lib/replace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/lib/replace.c b/source3/lib/replace.c index cd48b8d160..fe1cfc04eb 100644 --- a/source3/lib/replace.c +++ b/source3/lib/replace.c @@ -65,6 +65,9 @@ ftruncate for operating systems that don't have it size_t len2 = strlen(s); size_t ret = len1 + len2; + if (len1 >= bufsize) { + return 0; + } if (len1+len2 >= bufsize) { len2 = bufsize - (len1+1); } -- cgit From c8549363f49ac9ea818bd782319e57154764992f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 19 Mar 2004 14:31:09 +0000 Subject: add privileges support to ldapsam too (This used to be commit d940a2f77377dd1560cea4c782823cf9cd97a3aa) --- source3/include/smbldap.h | 4 + source3/lib/privileges.c | 2 +- source3/lib/smbldap.c | 10 ++ source3/param/loadparm.c | 11 ++ source3/passdb/pdb_ldap.c | 317 +++++++++++++++++++++++++++++++++++++++++ source3/utils/net_privileges.c | 45 +++--- 6 files changed, 361 insertions(+), 28 deletions(-) diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 68a2c00afe..119479f218 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -38,6 +38,7 @@ #define LDAP_OBJ_IDPOOL "sambaUnixIdPool" #define LDAP_OBJ_IDMAP_ENTRY "sambaIdmapEntry" #define LDAP_OBJ_SID_ENTRY "sambaSidEntry" +#define LDAP_OBJ_PRIVILEGE "sambaPrivilege" #define LDAP_OBJ_ACCOUNT "account" #define LDAP_OBJ_POSIXACCOUNT "posixAccount" @@ -49,6 +50,7 @@ #define LDAP_ATTRIBUTE_SID "sambaSID" #define LDAP_ATTRIBUTE_UIDNUMBER "uidNumber" #define LDAP_ATTRIBUTE_GIDNUMBER "gidNumber" +#define LDAP_ATTRIBUTE_SID_LIST "sambaSIDList" /* attribute map table indexes */ @@ -93,6 +95,7 @@ #define LDAP_ATTR_MUNGED_DIAL 37 #define LDAP_ATTR_BAD_PASSWORD_TIME 38 #define LDAP_ATTR_MOD_TIMESTAMP 39 +#define LDAP_ATTR_SID_LIST 40 typedef struct _attrib_map_entry { int attrib; @@ -106,6 +109,7 @@ extern ATTRIB_MAP_ENTRY attrib_map_v22[]; extern ATTRIB_MAP_ENTRY attrib_map_v30[]; extern ATTRIB_MAP_ENTRY dominfo_attr_list[]; extern ATTRIB_MAP_ENTRY groupmap_attr_list[]; +extern ATTRIB_MAP_ENTRY privilege_attr_list[]; extern ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[]; extern ATTRIB_MAP_ENTRY idpool_attr_list[]; extern ATTRIB_MAP_ENTRY sidmap_attr_list[]; diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c index cd888b6513..ce647f02cd 100644 --- a/source3/lib/privileges.c +++ b/source3/lib/privileges.c @@ -33,7 +33,7 @@ PRIVS privs[] = { {SE_ASSIGN_PRIMARY_TOKEN, "SeAssignPrimaryTokenPrivilege", "Assign Primary Token"}, {SE_LOCK_MEMORY, "SeLockMemoryPrivilege", "Lock Memory"}, {SE_INCREASE_QUOTA, "SeIncreaseQuotaPrivilege", "Increase Quota"}, - {SE_UNSOLICITED_INPUT, "eUnsolicitedInputPrivilege", "Unsolicited Input"}, + {SE_UNSOLICITED_INPUT, "SeUnsolicitedInputPrivilege", "Unsolicited Input"}, {SE_MACHINE_ACCOUNT, "SeMachineAccountPrivilege", "Can add Machine Accounts to the Domain"}, {SE_TCB, "SeTcbPrivilege", "TCB"}, {SE_SECURITY, "SeSecurityPrivilege", "Security Privilege"}, diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 20c2163cde..c2dcd905ea 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -155,6 +155,16 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { { LDAP_ATTR_LIST_END, NULL } }; +/* privileges */ + +ATTRIB_MAP_ENTRY privilege_attr_list[] = { + { LDAP_ATTR_CN, "sambaPrivName" }, + { LDAP_ATTR_SID_LIST, LDAP_ATTRIBUTE_SID_LIST }, + { LDAP_ATTR_DESC, "description" }, + { LDAP_ATTR_OBJCLASS, "objectClass" }, + { LDAP_ATTR_LIST_END, NULL } +}; + /********************************************************************** perform a simple table lookup and return the attribute name **********************************************************************/ diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index a72f7f878b..b5372188de 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -224,6 +224,7 @@ typedef struct char *szLdapUserSuffix; char *szLdapIdmapSuffix; char *szLdapGroupSuffix; + char *szLdapPrivilegeSuffix; #ifdef WITH_LDAP_SAMCONFIG int ldap_port; char *szLdapServer; @@ -1074,6 +1075,7 @@ static struct parm_struct parm_table[] = { {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED}, {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED}, {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED}, + {"ldap privilege suffix", P_STRING, P_GLOBAL, &Globals.szLdapPrivilegeSuffix, NULL, NULL, FLAG_ADVANCED}, {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED}, {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED}, {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED}, @@ -1471,6 +1473,7 @@ static void init_globals(void) string_set(&Globals.szLdapUserSuffix, ""); string_set(&Globals.szLdapGroupSuffix, ""); string_set(&Globals.szLdapIdmapSuffix, ""); + string_set(&Globals.szLdapPrivilegeSuffix, ""); string_set(&Globals.szLdapAdminDn, ""); Globals.ldap_ssl = LDAP_SSL_ON; @@ -2961,6 +2964,14 @@ char *lp_ldap_idmap_suffix(void) return lp_string(Globals.szLdapSuffix); } +char *lp_ldap_privilege_suffix(void) +{ + if (Globals.szLdapPrivilegeSuffix[0]) + return append_ldap_suffix(Globals.szLdapPrivilegeSuffix); + + return lp_string(Globals.szLdapSuffix); +} + /*************************************************************************** ***************************************************************************/ diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 2141f2a3f1..da5bfbecbb 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -2329,6 +2329,318 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods, return NT_STATUS_OK; } +/********************************************************************** + Privileges related functions + *********************************************************************/ + +static NTSTATUS ldapsam_modify_sid_list_for_privilege(struct pdb_methods *my_methods, const char *privname, const DOM_SID *sid, int ldap_op) +{ + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + LDAPMessage *entry = NULL; + LDAPMod **mods = NULL; + fstring sid_str; + fstring filter; + char **attr_list, *dn; + int rc, i; + + if ((sid == NULL) || (!sid_to_string(sid_str, sid))) { + DEBUG(3, ("ldapsam_modify_sid_list_for_privilege: Invalid SID\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + pstr_sprintf(filter, "(&(objectclass=%s)(sambaPrivName=%s))", LDAP_OBJ_PRIVILEGE, privname); + attr_list = get_attr_list(privilege_attr_list); + rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_privilege_suffix(), + LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &ldap_state->result); + free_attr_list(attr_list); + + + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ldapsam_modify_sid_list_for_privilege: LDAP search failed: %s\n", ldap_err2string(rc))); + DEBUG(3, ("ldapsam_modify_sid_list_for_privilege: Query was: %s, %s\n", lp_ldap_privilege_suffix(), filter)); + ldap_msgfree(ldap_state->result); + ldap_state->result = NULL; + goto done; + } + + if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) { + /* if the privilege does not exist and we are adding then + * create it */ + if (ldap_op == LDAP_MOD_ADD) { + + DEBUG(3, ("Privilege not found on ldap tree, creating a new entry\n")); + if (asprintf(&dn, "sambaPrivName=%s,%s", privname, lp_ldap_privilege_suffix()) < 0) { + DEBUG(0, ("ldapsam_modify_sid_list_for_privilege: Out of memory\n")); + goto done; + } + + smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaPrivName", privname); + + smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_PRIVILEGE); + + rc = smbldap_add(ldap_state->smbldap_state, dn, mods); + + if (rc != LDAP_SUCCESS) { + char *ld_error = NULL; + + ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); + DEBUG(1, + ("ldapsam_modify_sid_list_for_privilege:" + "Failed to add privilege (%s) dn= %s with: %s\n\t%s\n", + privname, + dn, ldap_err2string(rc), + ld_error ? ld_error : "unknown") + ); + + SAFE_FREE(ld_error); + goto done; + } + + pstr_sprintf(filter, "(&(objectclass=%s)(sambaPrivName=%s))", LDAP_OBJ_PRIVILEGE, privname); + attr_list = get_attr_list(privilege_attr_list); + rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_privilege_suffix(), + LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &ldap_state->result); + free_attr_list(attr_list); + + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ldapsam_modify_sid_list_for_privilege: LDAP search failed: %s\n", ldap_err2string(rc))); + DEBUG(3, ("ldapsam_modify_sid_list_for_privilege: Query was: %s, %s\n", lp_ldap_privilege_suffix(), filter)); + ldap_msgfree(ldap_state->result); + ldap_state->result = NULL; + goto done; + } + } else { + goto done; + } + } + /* entry found */ + entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result); + + /* retrieve the dn */ + dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry); + if (!dn) { + goto done; + } + + /* prepare the modification */ + smbldap_set_mod(&mods, ldap_op, "sambaSIDList", sid_str); + + /* modify the privilege */ + rc = smbldap_modify(ldap_state->smbldap_state, dn, mods); + + /* free used structures */ + ldap_mods_free(mods, True); + + if (rc != LDAP_SUCCESS) { + char *ld_error = NULL; + + ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); + DEBUG(1, + ("ldapsam_modify_sid_list_for_privilege:" + "Failed to %s sid for privilege (%s) dn= %s with: %s\n\t%s\n", + (ldap_op == LDAP_MOD_ADD) ? "add" : "remove", + privname, + dn, ldap_err2string(rc), + ld_error ? ld_error : "unknown") + ); + SAFE_FREE(ld_error); + goto done; + } + + ret = NT_STATUS_OK; + +done: + return ret; +} + +static NTSTATUS ldapsam_add_sid_to_privilege(struct pdb_methods *my_methods, const char *privname, const DOM_SID *sid) +{ + return ldapsam_modify_sid_list_for_privilege(my_methods, privname, sid, LDAP_MOD_ADD); +} + +static NTSTATUS ldapsam_remove_sid_from_privilege(struct pdb_methods *my_methods, const char *privname, const DOM_SID *sid) +{ + return ldapsam_modify_sid_list_for_privilege(my_methods, privname, sid, LDAP_MOD_DELETE); +} + +static NTSTATUS ldapsam_get_privilege_set(struct pdb_methods *my_methods, NT_USER_TOKEN *token, PRIVILEGE_SET *privset) +{ + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + LDAPMessage *entry = NULL; + fstring sid_str; + fstring filter; + char **sid_list; + char **attr_list; + int rc, i; + + sid_list = (char **)malloc(sizeof(char *) * (token->num_sids + 1)); + for (i = 0; i < token->num_sids; i++) { + sid_to_string(sid_str, &token->user_sids[i]); + sid_list[i] = strdup(sid_str); + if ( ! sid_list[i]) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } + } + sid_list[i] = NULL; + + pstr_sprintf(filter, "(objectclass=%s)", LDAP_OBJ_PRIVILEGE); + attr_list = get_attr_list(privilege_attr_list); + rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_privilege_suffix(), + LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &ldap_state->result); + free_attr_list(attr_list); + + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ldapsam_get_privilege_set: LDAP search failed: %s\n", ldap_err2string(rc))); + DEBUG(3, ("ldapsam_get_privilege_set: Query was: %s, %s\n", lp_ldap_privilege_suffix(), filter)); + ldap_msgfree(ldap_state->result); + ldap_state->result = NULL; + goto done; + } + + if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) { + DEBUG(3, ("ldapsam_get_privilege_set: No privileges in ldap tree\n")); + ret = NT_STATUS_OK; + goto done; + } + + DEBUG(2, ("ldapsam_get_privilege_set: %d entries in the base!\n", + ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result))); + + entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result); + + while (entry != NULL) { + char **values = NULL; + + for(i=0; sid_list[i] != NULL; i++) { + char *c, *s; + pstring privname; + int j; + + if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, "sambaPrivName", privname, sizeof(pstring))) { + goto loop; + } + + if ((values = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID_LIST)) == NULL) { + DEBUG(10, ("ldapsam_get_privilege_set: SID List not found skipping privilege\n")); + goto loop; + } + + j = 0; + while (values[j] != 0) { + if (strcmp(values[j], sid_list[i]) == 0) { + DEBUG(10, ("sid [%s] found in users sid list\n", sid_list[i])); + DEBUG(10, ("adding privilege [%s] to the users privilege list\n", privname)); + add_privilege_by_name(privset, privname); + goto loop; + } + j++; + } + + if (values) { + ldap_value_free(values); + values = NULL; + } + } + loop: + if (values) { + ldap_value_free(values); + } + + entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct, entry); + } + + ret = NT_STATUS_OK; + +done: + i = 0; + while (sid_list[i]) { + free(sid_list[i]); + i++; + } + free(sid_list); + + return ret; +} + +static NTSTATUS ldapsam_get_privilege_entry(struct pdb_methods *my_methods, const char *privname, + char **sid_list) +{ + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + LDAPMessage *entry = NULL; + fstring sid_str; + fstring filter; + char **attr_list, **values; + int rc, i, len; + + *sid_list = NULL; + pstr_sprintf(filter, "(&(objectclass=%s)(sambaPrivName=%s))", LDAP_OBJ_PRIVILEGE, privname); + attr_list = get_attr_list(privilege_attr_list); + rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_privilege_suffix(), + LDAP_SCOPE_SUBTREE, filter, + attr_list, 0, &ldap_state->result); + free_attr_list(attr_list); + + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ldapsam_get_privilege_entry: LDAP search failed: %s\n", ldap_err2string(rc))); + DEBUG(3, ("ldapsam_get_privilege_entry: Query was: %s, %s\n", lp_ldap_privilege_suffix(), filter)); + ldap_msgfree(ldap_state->result); + ldap_state->result = NULL; + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, ldap_state->result) == 0) { + DEBUG(3, ("ldapsam_get_privilege_entry: No such privilege (%s) in ldap tree\n", privname)); + goto done; + } + + entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result); + + if ((values = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID_LIST)) == NULL) { + DEBUG(10, ("ldapsam_get_privilege_entry: SID List not found skipping privilege\n")); + ret = NT_STATUS_OK; + goto done; + } + + for (i = 0, len = 0; values[i] != 0; i++ ) { + len = len + strlen(values[i]) + 1; + } + + *sid_list = (char *)malloc(len); + if ((*sid_list) == NULL) { + DEBUG(0, ("ldapsam_get_privilege_entry: Out of memory!\n")); + ldap_value_free(values); + ret = NT_STATUS_NO_MEMORY; + goto done; + } + + (*sid_list)[0] = '\0'; + + for (i = 0; values[i] != 0; i++ ) { + if (i != 0) { + strlcat(*sid_list, ",", len); + } + DEBUG(0, ("sid_list = [%s]\n", *sid_list)); + DEBUG(0, ("values = [%s]\n", values[i])); + DEBUG(0, ("len = [%d]\n", len)); + strlcat(*sid_list, values[i], len); + DEBUG(0, ("sid_list = [%s]\n", *sid_list)); + } + + ldap_value_free(values); + ret = NT_STATUS_OK; +done: + return ret; +} + + /********************************************************************** Housekeeping *********************************************************************/ @@ -2382,6 +2694,11 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS ** (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry; (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping; + (*pdb_method)->add_sid_to_privilege = ldapsam_add_sid_to_privilege; + (*pdb_method)->remove_sid_from_privilege = ldapsam_remove_sid_from_privilege; + (*pdb_method)->get_privilege_set = ldapsam_get_privilege_set; + (*pdb_method)->get_privilege_entry = ldapsam_get_privilege_entry; + /* TODO: Setup private data and free */ ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(*ldap_state)); diff --git a/source3/utils/net_privileges.c b/source3/utils/net_privileges.c index 2e8bfe0c83..62f2da33ee 100644 --- a/source3/utils/net_privileges.c +++ b/source3/utils/net_privileges.c @@ -69,13 +69,13 @@ static void print_priv_entry(const char *privname, const char *description, cons return; } - if (!description) - d_printf("%s\n", privname); - else { - d_printf("%s\n", privname); + d_printf("%s\n", privname); + + if (description) { d_printf("\tdescription: %s\n", description); - d_printf("\tSIDS: %s\n", sid_list); } + + d_printf("\tSIDS: %s\n", sid_list); } /********************************************************* @@ -83,17 +83,13 @@ static void print_priv_entry(const char *privname, const char *description, cons **********************************************************/ static int net_priv_list(int argc, const char **argv) { - BOOL long_list = False; fstring privname = ""; fstring sid_string = ""; int i; /* get the options */ for ( i=0; i Date: Fri, 19 Mar 2004 15:52:16 +0000 Subject: wrap cli_tdis() in check to make sure we have a valid cnum (This used to be commit e54342b062e7736b46f56bcb0e064acc5a7b98ee) --- source3/libsmb/clientgen.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 28da73894f..370249d047 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -367,15 +367,16 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) void cli_close_connection(struct cli_state *cli) { - /* - * tell our peer to free his resources. Wihtout this, when an - * application attempts to do a graceful shutdown and calls - * smbc_free_context() to clean up all connections, some connections - * can remain active on the peer end, until some (long) timeout period - * later. This tree disconnect forces the peer to clean up, since the - * connection will be going away. - */ - cli_tdis(cli); + /* + * tell our peer to free his resources. Wihtout this, when an + * application attempts to do a graceful shutdown and calls + * smbc_free_context() to clean up all connections, some connections + * can remain active on the peer end, until some (long) timeout period + * later. This tree disconnect forces the peer to clean up, since the + * connection will be going away. + */ + if ( cli->cnum != -1 ) + cli_tdis(cli); cli_nt_session_close(cli); cli_nt_netlogon_netsec_session_close(cli); -- cgit From 9f68ccb8027ffa9c9875ad2b327c33a1eeb3ffab Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Mar 2004 16:21:50 +0000 Subject: cleaning up a few compiler warngings (This used to be commit 8ceefd5438a1071a262a7db234c9857fbad05147) --- source3/libsmb/cliconnect.c | 1 - source3/libsmb/clientgen.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 938d6fd29b..8093d79452 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1661,7 +1661,6 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user struct ip_service *ip_list; struct cli_state *cli; int i, count; - struct in_addr server_ip; DEBUG(99, ("Do broadcast lookup for workgroups on local network\n")); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 370249d047..66edc3ce38 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -375,7 +375,7 @@ void cli_close_connection(struct cli_state *cli) * later. This tree disconnect forces the peer to clean up, since the * connection will be going away. */ - if ( cli->cnum != -1 ) + if ( cli->cnum != (uint16)-1 ) cli_tdis(cli); cli_nt_session_close(cli); -- cgit From 14f5ea9965eb1455c25fa80a8e58e31a20ef37b6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Mar 2004 16:59:59 +0000 Subject: add --with-libdir and --with-mandir (patch from Guenther Deschner) (This used to be commit 649e1c372e0a407d8283cc1d938376ac4ad8e525) --- source3/configure.in | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index 806c53edaf..c58f640a00 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -105,7 +105,7 @@ AC_ARG_WITH(swatdir, ################################################# # set configuration directory location AC_ARG_WITH(configdir, -[ --with-configdir=DIR Where to put configuration files (\$libdir)], +[ --with-configdir=DIR Where to put configuration files ($libdir)], [ case "$withval" in yes|no) # @@ -121,7 +121,7 @@ AC_ARG_WITH(configdir, ################################################# # set log directory location AC_ARG_WITH(logfilebase, -[ --with-logfilebase=DIR Where to put log files (\$(VARDIR))], +[ --with-logfilebase=DIR Where to put log files ($VARDIR)], [ case "$withval" in yes|no) # @@ -134,6 +134,38 @@ AC_ARG_WITH(logfilebase, ;; esac]) +################################################# +# set lib directory location +AC_ARG_WITH(libdir, +[ --with-libdir=DIR Where to put libdir ($libdir)], +[ case "$withval" in + yes|no) + # + # Just in case anybody does it + # + AC_MSG_WARN([--with-libdir without argument - will use default]) + ;; + * ) + libdir="$withval" + ;; + esac]) + +################################################# +# set lib directory location +AC_ARG_WITH(mandir, +[ --with-mandir=DIR Where to put man pages ($mandir)], +[ case "$withval" in + yes|no) + # + # Just in case anybody does it + # + AC_MSG_WARN([--with-mandir without argument - will use default]) + ;; + * ) + mandir="$withval" + ;; + esac]) + AC_ARG_WITH(cfenc, [ --with-cfenc=HEADERDIR Use internal CoreFoundation encoding API for optimization (Mac OS X/Darwin only)], -- cgit From 8d976560e07ccf11ac49926ee742ca41ff77c248 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 19 Mar 2004 17:36:56 +0000 Subject: Apply some more of Derrell Lipman's changes. (This used to be commit a6457e1c817663cf5f3e77e4dd431ac0d9184dc7) --- examples/libsmbclient/Makefile | 6 ++- examples/libsmbclient/testbrowse.c | 91 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 examples/libsmbclient/testbrowse.c diff --git a/examples/libsmbclient/Makefile b/examples/libsmbclient/Makefile index e7c82a3aee..fcd5ef2900 100644 --- a/examples/libsmbclient/Makefile +++ b/examples/libsmbclient/Makefile @@ -10,7 +10,7 @@ CFLAGS = -I$(SAMBA_INCL) $(EXTLIB_INCL) LDFLAGS = -L/usr/lib -all: testsmbc tree testacl +all: testsmbc tree testacl testbrowse testsmbc: testsmbc.o @echo Linking testsmbc @@ -28,5 +28,9 @@ testacl: testacl.o @echo Linking testacl @$(CC) `gtk-config --cflags` $(CFLAGS) $(LDFLAGS) -o $@ `gtk-config --libs` -lsmbclient -lpopt $< +testbrowse: testbrowse.o + @echo Linking testbrowse + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -lsmbclient -lpopt $< + clean: @rm -f *.o *~ diff --git a/examples/libsmbclient/testbrowse.c b/examples/libsmbclient/testbrowse.c new file mode 100644 index 0000000000..d2472230a2 --- /dev/null +++ b/examples/libsmbclient/testbrowse.c @@ -0,0 +1,91 @@ +/* + Unix SMB/CIFS implementation. + SMB client library test program for browsing with different master browsers + Copyright (C) Derrell Lipman 2004 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include + +static void +auth_fn(const char * pServer, + const char * pShare, + char * pWorkgroup, + int workgroup_len, + char * pUsername, + int username_len, + char * pPassword, + int password_len) + +{ + strncpy(pUsername, "anonymous", username_len); /* doesn't matter what */ + strncpy(pPassword, "password", password_len); /* ditto */ +} + + +int +main(int argc, char * argv[]) +{ + int debug = 4; + int opt; + char * p; + char buf[1024]; + int dir; + struct smbc_dirent * dirent; + char ** ppUrl; + char * urlList[] = + { + "smb://", + "smb://?mb=.any", + "smb://?mb=.all", + "smb://?mb=xx", /* this one is suupposed to fail */ + NULL + }; + + if (smbc_init(auth_fn, debug) != 0) + { + printf("Could not initialize smbc_ library\n"); + return 1; + } + + for (ppUrl = urlList; *ppUrl != NULL; ppUrl++) + { + printf("Opening (%s)...\n", *ppUrl); + + if ((dir = smbc_opendir(*ppUrl)) < 0) + { + printf("Could not open [%s] (%d:%s)\n", + *ppUrl, errno, strerror(errno)); + continue; + } + + while ((dirent = smbc_readdir(dir)) != NULL) + { + printf("%s\n", dirent->name); + } + + smbc_closedir(dir); + } + + exit(0); +} + -- cgit