From b3f2a3a488f868c4aa31c49bc145a8a6e81de3b5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 28 May 2009 15:32:55 +0200 Subject: s3-winbindd: fix remaining callers of sid_binstring(). Guenther --- source3/winbindd/idmap_adex/gc_util.c | 4 ++-- source3/winbindd/idmap_adex/provider_unified.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/winbindd/idmap_adex/gc_util.c b/source3/winbindd/idmap_adex/gc_util.c index 58e641b630..879c2e0ecf 100644 --- a/source3/winbindd/idmap_adex/gc_util.c +++ b/source3/winbindd/idmap_adex/gc_util.c @@ -716,11 +716,11 @@ done: *name = NULL; - sid_string = sid_binstring(sid); + sid_string = sid_binstring(frame, sid); BAIL_ON_PTR_ERROR(sid_string, nt_status); filter = talloc_asprintf(frame, "(objectSid=%s)", sid_string); - SAFE_FREE(sid_string); + TALLOC_FREE(sid_string); BAIL_ON_PTR_ERROR(filter, nt_status); nt_status = gc_search_all_forests_unique(filter, &ads, &msg); diff --git a/source3/winbindd/idmap_adex/provider_unified.c b/source3/winbindd/idmap_adex/provider_unified.c index f9d73f5f95..00db018de2 100644 --- a/source3/winbindd/idmap_adex/provider_unified.c +++ b/source3/winbindd/idmap_adex/provider_unified.c @@ -483,11 +483,11 @@ static NTSTATUS search_forest(struct likewise_cell *forest_cell, switch (fdata->ftype) { case SidFilter: - sid_binstr = sid_binstring(&fdata->filter.sid); + sid_binstr = sid_binstring(frame, &fdata->filter.sid); BAIL_ON_PTR_ERROR(sid_binstr, nt_status); filter = talloc_asprintf(frame, "(objectSid=%s)", sid_binstr); - SAFE_FREE(sid_binstr); + TALLOC_FREE(sid_binstr); break; case IdFilter: filter = build_id_filter(fdata->filter.id.id, -- cgit From de4c13ca682671d46d9d6512f84670c88b2e7837 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Fri, 29 May 2009 16:10:19 +0800 Subject: s3: fix building of pam_smbpass. Signed-off-by: Bo Yang --- source3/pam_smbpass/support.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source3/pam_smbpass/support.c b/source3/pam_smbpass/support.c index 855885a6d7..98dda4e8cc 100644 --- a/source3/pam_smbpass/support.c +++ b/source3/pam_smbpass/support.c @@ -21,7 +21,21 @@ #include "support.h" #include "../libcli/auth/libcli_auth.h" +#if defined(HAVE_SECURITY_PAM_EXT_H) +#include +#elif defined(HAVE_PAM_PAM_EXT_H) +#include +#endif + +#if defined(HAVE_SECURITY__PAM_MACROS_H) +#include +#elif defined(HAVE_PAM__PAM_MACROS_H) +#include +#endif +#ifdef HAVE_SYSLOG_H +#include +#endif #define _pam_overwrite(x) \ do { \ -- cgit From d74e42e0eca0bb15c12fa51f125d905a6cee5db5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 28 May 2009 13:05:50 -0700 Subject: Make getfacl async. Jeremy. --- source3/client/client.c | 8 +-- source3/include/proto.h | 14 +++- source3/libsmb/clifile.c | 170 ++++++++++++++++++++++++++++++++++++----------- 3 files changed, 145 insertions(+), 47 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 2edeb1ae2b..0e874ec171 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -3043,17 +3043,16 @@ static int cmd_getfacl(void) return 1; } - if (!cli_unix_getfacl(targetcli, targetname, &rb_size, &retbuf)) { + if (!NT_STATUS_IS_OK(cli_posix_getfacl(targetcli, targetname, ctx, &rb_size, &retbuf))) { d_printf("%s getfacl file %s\n", cli_errstr(targetcli), src); return 1; } /* ToDo : Print out the ACL values. */ - if (SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION || rb_size < 6) { + if (rb_size < 6 || SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION) { d_printf("getfacl file %s, unknown POSIX acl version %u.\n", src, (unsigned int)CVAL(retbuf,0) ); - SAFE_FREE(retbuf); return 1; } @@ -3064,8 +3063,6 @@ static int cmd_getfacl(void) src, (unsigned int)(SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)), (unsigned int)rb_size); - - SAFE_FREE(retbuf); return 1; } @@ -3150,7 +3147,6 @@ static int cmd_getfacl(void) d_printf("%s\n", perms_to_string(permstring, perms)); } - SAFE_FREE(retbuf); return 0; } diff --git a/source3/include/proto.h b/source3/include/proto.h index 2217b3315b..60810cc921 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2361,7 +2361,19 @@ NTSTATUS cli_posix_hardlink(struct cli_state *cli, const char *newname); uint32_t unix_perms_to_wire(mode_t perms); mode_t wire_perms_to_unix(uint32_t perms); -bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf); +struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + size_t *prb_size, + char **retbuf); +NTSTATUS cli_posix_getfacl(struct cli_state *cli, + const char *fname, + TALLOC_CTX *mem_ctx, + size_t *prb_size, + char **retbuf); bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf); bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode); bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 187fcdf625..be2e81204d 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -453,7 +453,6 @@ NTSTATUS cli_posix_readlink(struct cli_state *cli, const char *fname, return status; } - /**************************************************************************** Hard link a file (UNIX extensions). ****************************************************************************/ @@ -624,58 +623,149 @@ static mode_t unix_filetype_from_wire(uint32_t wire_type) Do a POSIX getfacl (UNIX extensions). ****************************************************************************/ -bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf) +struct getfacl_state { + uint16_t setup; + uint8_t *param; + uint32_t num_data; + uint8_t *data; +}; + +static void cli_posix_getfacl_done(struct tevent_req *subreq) { - unsigned int param_len = 0; - unsigned int data_len = 0; - uint16_t setup = TRANSACT2_QPATHINFO; - char *param; - size_t nlen = 2*(strlen(name)+1); - char *rparam=NULL, *rdata=NULL; - char *p; + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct getfacl_state *state = tevent_req_data(req, struct getfacl_state); + NTSTATUS status; - param = SMB_MALLOC_ARRAY(char, 6+nlen+2); - if (!param) { - return false; + status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, + &state->data, &state->num_data); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + tevent_req_done(req); +} - p = param; - memset(p, '\0', 6); - SSVAL(p, 0, SMB_QUERY_POSIX_ACL); - p += 6; - p += clistr_push(cli, p, name, nlen, STR_TERMINATE); - param_len = PTR_DIFF(p, param); +struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct link_state *state = NULL; - if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, 0, cli->max_xmit /* data, length, max */ - )) { - SAFE_FREE(param); - return false; + req = tevent_req_create(mem_ctx, &state, struct getfacl_state); + if (req == NULL) { + return NULL; } - SAFE_FREE(param); + /* Setup setup word. */ + SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO); - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return false; + /* Setup param array. */ + state->param = talloc_array(state, uint8_t, 6); + if (tevent_req_nomem(state->param, req)) { + return tevent_req_post(req, ev); } + memset(state->param, '\0', 6); + SSVAL(state->param, 0, SMB_QUERY_POSIX_ACL); - if (data_len < 6) { - SAFE_FREE(rdata); - SAFE_FREE(rparam); - return false; + state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname, + strlen(fname)+1, NULL); + + if (tevent_req_nomem(state->param, req)) { + return tevent_req_post(req, ev); } - SAFE_FREE(rparam); - *retbuf = rdata; - *prb_size = (size_t)data_len; + subreq = cli_trans_send(state, /* mem ctx. */ + ev, /* event ctx. */ + cli, /* cli_state. */ + SMBtrans2, /* cmd. */ + NULL, /* pipe name. */ + -1, /* fid. */ + 0, /* function. */ + 0, /* flags. */ + &state->setup, /* setup. */ + 1, /* num setup uint16_t words. */ + 0, /* max returned setup. */ + state->param, /* param. */ + talloc_get_size(state->param), /* num param. */ + 2, /* max returned param. */ + NULL, /* data. */ + 0, /* num data. */ + cli->max_xmit); /* max returned data. */ - return true; + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_posix_getfacl_done, req); + return req; +} + +NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + size_t *prb_size, + char **retbuf) +{ + struct getfacl_state *state = tevent_req_data(req, struct getfacl_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + *prb_size = (size_t)state->num_data; + *retbuf = (char *)talloc_move(mem_ctx, &state->data); + return NT_STATUS_OK; +} + +NTSTATUS cli_posix_getfacl(struct cli_state *cli, + const char *fname, + TALLOC_CTX *mem_ctx, + size_t *prb_size, + char **retbuf) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_posix_getfacl_send(frame, + ev, + cli, + fname); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_getfacl_recv(req, mem_ctx, prb_size, retbuf); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** -- cgit From fbca26923915a70031f561b198cfe2cc0d9c3aa6 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Wed, 27 May 2009 17:14:49 -0700 Subject: s3/auth map NULL domains to our global sam name This is an addendum to d8c54fdd, which made make_user_info_map() match Windows behavior by mapping untrusted domains given to smbd on the wire with the users credentials to smbd's global sam name. This fix was being circumvented in the case where the client passed a NULL domain. Vista clients do this. In that case smbd was always remapping the name to the machine workgroup. The NULL domain case should also be mapped to the global sam name. Removing the code in this patch, causes us to fall down to the logic added in d8c54fdd and properly map the domain. --- source3/auth/auth_util.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index a27025fc8d..9d29987c0d 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -208,21 +208,15 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n", client_domain, smb_name, wksta_name)); - /* don't allow "" as a domain, fixes a Win9X bug - where it doens't supply a domain for logon script - 'net use' commands. */ - - if ( *client_domain ) - domain = client_domain; - else - domain = lp_workgroup(); + domain = client_domain; /* If you connect to a Windows domain member using a bogus domain name, * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if * the Windows box is a DC the name will become DOMAIN\user and be * authenticated against AD, if the Windows box is a member server but * not a DC the name will become WORKSTATION\user. A standalone - * non-domain member box will also map to WORKSTATION\user. */ + * non-domain member box will also map to WORKSTATION\user. + * This also deals with the client passing in a "" domain */ if (!is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) ) -- cgit From 656e86d5fa876131fc8e373f0c2100f4bef1cc26 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 28 May 2009 13:32:00 -0700 Subject: Make cli_posix_stat() async. Jeremy. --- source3/client/client.c | 4 +- source3/include/proto.h | 10 ++- source3/libsmb/clifile.c | 195 ++++++++++++++++++++++++++++++++++------------- 3 files changed, 154 insertions(+), 55 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 0e874ec171..7e98dea91c 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -3037,7 +3037,7 @@ static int cmd_getfacl(void) return 1; } - if (!cli_unix_stat(targetcli, targetname, &sbuf)) { + if (!NT_STATUS_IS_OK(cli_posix_stat(targetcli, targetname, &sbuf))) { d_printf("%s getfacl doing a stat on file %s\n", cli_errstr(targetcli), src); return 1; @@ -3188,7 +3188,7 @@ static int cmd_stat(void) return 1; } - if (!cli_unix_stat(targetcli, targetname, &sbuf)) { + if (!NT_STATUS_IS_OK(cli_posix_stat(targetcli, targetname, &sbuf))) { d_printf("%s stat file %s\n", cli_errstr(targetcli), src); return 1; diff --git a/source3/include/proto.h b/source3/include/proto.h index 60810cc921..af68ae74a0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2374,7 +2374,15 @@ NTSTATUS cli_posix_getfacl(struct cli_state *cli, TALLOC_CTX *mem_ctx, size_t *prb_size, char **retbuf); -bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf); +struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_posix_stat_recv(struct tevent_req *req, + SMB_STRUCT_STAT *sbuf); +NTSTATUS cli_posix_stat(struct cli_state *cli, + const char *fname, + SMB_STRUCT_STAT *sbuf); bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode); bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid); struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index be2e81204d..4c5dc3bd19 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -772,85 +772,176 @@ NTSTATUS cli_posix_getfacl(struct cli_state *cli, Stat a file (UNIX extensions). ****************************************************************************/ -bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf) +struct stat_state { + uint16_t setup; + uint8_t *param; + uint32_t num_data; + uint8_t *data; +}; + +static void cli_posix_stat_done(struct tevent_req *subreq) { - unsigned int param_len = 0; - unsigned int data_len = 0; - uint16_t setup = TRANSACT2_QPATHINFO; - char *param; - size_t nlen = 2*(strlen(name)+1); - char *rparam=NULL, *rdata=NULL; - char *p; + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct stat_state *state = tevent_req_data(req, struct stat_state); + NTSTATUS status; + + status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, + &state->data, &state->num_data); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + tevent_req_done(req); +} - ZERO_STRUCTP(sbuf); +struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct stat_state *state = NULL; - param = SMB_MALLOC_ARRAY(char, 6+nlen+2); - if (!param) { - return false; + req = tevent_req_create(mem_ctx, &state, struct stat_state); + if (req == NULL) { + return NULL; } - p = param; - memset(p, '\0', 6); - SSVAL(p, 0, SMB_QUERY_FILE_UNIX_BASIC); - p += 6; - p += clistr_push(cli, p, name, nlen, STR_TERMINATE); - param_len = PTR_DIFF(p, param); - if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, 0, cli->max_xmit /* data, length, max */ - )) { - SAFE_FREE(param); - return false; + /* Setup setup word. */ + SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO); + + /* Setup param array. */ + state->param = talloc_array(state, uint8_t, 6); + if (tevent_req_nomem(state->param, req)) { + return tevent_req_post(req, ev); } + memset(state->param, '\0', 6); + SSVAL(state->param, 0, SMB_QUERY_FILE_UNIX_BASIC); - SAFE_FREE(param); + state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname, + strlen(fname)+1, NULL); - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return false; + if (tevent_req_nomem(state->param, req)) { + return tevent_req_post(req, ev); } - if (data_len < 96) { - SAFE_FREE(rdata); - SAFE_FREE(rparam); - return false; + subreq = cli_trans_send(state, /* mem ctx. */ + ev, /* event ctx. */ + cli, /* cli_state. */ + SMBtrans2, /* cmd. */ + NULL, /* pipe name. */ + -1, /* fid. */ + 0, /* function. */ + 0, /* flags. */ + &state->setup, /* setup. */ + 1, /* num setup uint16_t words. */ + 0, /* max returned setup. */ + state->param, /* param. */ + talloc_get_size(state->param), /* num param. */ + 2, /* max returned param. */ + NULL, /* data. */ + 0, /* num data. */ + 96); /* max returned data. */ + + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } + tevent_req_set_callback(subreq, cli_posix_stat_done, req); + return req; +} - sbuf->st_ex_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */ - sbuf->st_ex_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */ +NTSTATUS cli_posix_stat_recv(struct tevent_req *req, + SMB_STRUCT_STAT *sbuf) +{ + struct stat_state *state = tevent_req_data(req, struct stat_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + + if (state->num_data != 96) { + return NT_STATUS_DATA_ERROR; + } + + sbuf->st_ex_size = IVAL2_TO_SMB_BIG_UINT(state->data,0); /* total size, in bytes */ + sbuf->st_ex_blocks = IVAL2_TO_SMB_BIG_UINT(state->data,8); /* number of blocks allocated */ #if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) sbuf->st_ex_blocks /= STAT_ST_BLOCKSIZE; #else /* assume 512 byte blocks */ sbuf->st_ex_blocks /= 512; #endif - sbuf->st_ex_ctime = interpret_long_date(rdata + 16); /* time of last change */ - sbuf->st_ex_atime = interpret_long_date(rdata + 24); /* time of last access */ - sbuf->st_ex_mtime = interpret_long_date(rdata + 32); /* time of last modification */ + sbuf->st_ex_ctime = interpret_long_date((char *)(state->data + 16)); /* time of last change */ + sbuf->st_ex_atime = interpret_long_date((char *)(state->data + 24)); /* time of last access */ + sbuf->st_ex_mtime = interpret_long_date((char *)(state->data + 32)); /* time of last modification */ - sbuf->st_ex_uid = (uid_t) IVAL(rdata,40); /* user ID of owner */ - sbuf->st_ex_gid = (gid_t) IVAL(rdata,48); /* group ID of owner */ - sbuf->st_ex_mode |= unix_filetype_from_wire(IVAL(rdata, 56)); + sbuf->st_ex_uid = (uid_t) IVAL(state->data,40); /* user ID of owner */ + sbuf->st_ex_gid = (gid_t) IVAL(state->data,48); /* group ID of owner */ + sbuf->st_ex_mode = unix_filetype_from_wire(IVAL(state->data, 56)); #if defined(HAVE_MAKEDEV) { - uint32_t dev_major = IVAL(rdata,60); - uint32_t dev_minor = IVAL(rdata,68); + uint32_t dev_major = IVAL(state->data,60); + uint32_t dev_minor = IVAL(state->data,68); sbuf->st_ex_rdev = makedev(dev_major, dev_minor); } #endif - sbuf->st_ex_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76); /* inode */ - sbuf->st_ex_mode |= wire_perms_to_unix(IVAL(rdata,84)); /* protection */ - sbuf->st_ex_nlink = IVAL(rdata,92); /* number of hard links */ + sbuf->st_ex_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(state->data,76); /* inode */ + sbuf->st_ex_mode |= wire_perms_to_unix(IVAL(state->data,84)); /* protection */ + sbuf->st_ex_nlink = IVAL(state->data,92); /* number of hard links */ - SAFE_FREE(rdata); - SAFE_FREE(rparam); + return NT_STATUS_OK; +} - return true; +NTSTATUS cli_posix_stat(struct cli_state *cli, + const char *fname, + SMB_STRUCT_STAT *sbuf) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_posix_stat_send(frame, + ev, + cli, + fname); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_stat_recv(req, sbuf); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } + /**************************************************************************** Chmod or chown a file internal (UNIX extensions). ****************************************************************************/ -- cgit From 9d373574e4cfc6eb7c238ab5ccfca26493b4376d Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Thu, 28 May 2009 13:34:28 -0700 Subject: s3 tdbtorture: Fix linking issue tdbtorture now calls the tdb transaction code and needs to link it appropriately --- source3/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 2b30b4a5bd..c7514a0b1d 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1186,7 +1186,7 @@ TDBTOOL_OBJ = @tdbdir@/tools/tdbtool.o $(LIBREPLACE_OBJ) \ TDBDUMP_OBJ = @tdbdir@/tools/tdbdump.o $(LIBREPLACE_OBJ) \ $(SOCKET_WRAPPER_OBJ) -TDBTORTURE_OBJ = @tdbdir@/tools/tdbtorture.o $(LIBREPLACE_OBJ) \ +TDBTORTURE_OBJ = @tdbdir@/tools/tdbtorture.o $(LIBTDB_OBJ) \ $(SOCKET_WRAPPER_OBJ) -- cgit From 0a455c12840cfb3ac23ee9fa0b79ebcc86a768da Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Thu, 28 May 2009 14:11:17 -0700 Subject: s3: Fix a few more users of stat to use stat_ex --- source3/smbd/dosmode.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 6468544748..eeed76329c 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -379,7 +379,7 @@ int dos_attributes_to_stat_dos_flags(uint32_t dosmode) } /**************************************************************************** - Gets DOS attributes, accessed via st_flags in the stat struct. + Gets DOS attributes, accessed via st_ex_flags in the stat struct. ****************************************************************************/ static bool get_stat_dos_flags(connection_struct *conn, @@ -396,15 +396,15 @@ static bool get_stat_dos_flags(connection_struct *conn, DEBUG(5, ("Getting stat dos attributes for %s.\n", fname)); - if (sbuf->st_flags & UF_DOS_ARCHIVE) + if (sbuf->st_ex_flags & UF_DOS_ARCHIVE) *dosmode |= aARCH; - if (sbuf->st_flags & UF_DOS_HIDDEN) + if (sbuf->st_ex_flags & UF_DOS_HIDDEN) *dosmode |= aHIDDEN; - if (sbuf->st_flags & UF_DOS_RO) + if (sbuf->st_ex_flags & UF_DOS_RO) *dosmode |= aRONLY; - if (sbuf->st_flags & UF_DOS_SYSTEM) + if (sbuf->st_ex_flags & UF_DOS_SYSTEM) *dosmode |= aSYSTEM; - if (sbuf->st_flags & UF_DOS_NOINDEX) + if (sbuf->st_ex_flags & UF_DOS_NOINDEX) *dosmode |= FILE_ATTRIBUTE_NONINDEXED; if (S_ISDIR(sbuf->st_ex_mode)) *dosmode |= aDIR; @@ -416,7 +416,7 @@ static bool get_stat_dos_flags(connection_struct *conn, } /**************************************************************************** - Sets DOS attributes, stored in st_flags of the inode. + Sets DOS attributes, stored in st_ex_flags of the inode. ****************************************************************************/ static bool set_stat_dos_flags(connection_struct *conn, @@ -439,15 +439,15 @@ static bool set_stat_dos_flags(connection_struct *conn, DEBUG(5, ("Setting stat dos attributes for %s.\n", fname)); - new_flags = (sbuf->st_flags & ~UF_DOS_FLAGS) | + new_flags = (sbuf->st_ex_flags & ~UF_DOS_FLAGS) | dos_attributes_to_stat_dos_flags(dosmode); /* Return early if no flags changed. */ - if (new_flags == sbuf->st_flags) + if (new_flags == sbuf->st_ex_flags) return true; DEBUG(5, ("Setting stat dos attributes=0x%x, prev=0x%x\n", new_flags, - sbuf->st_flags)); + sbuf->st_ex_flags)); /* Set new flags with chflags. */ error = SMB_VFS_CHFLAGS(conn, fname, new_flags); -- cgit From 5c623e6c2e787cad6efde036161e8a2f816d5203 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Thu, 28 May 2009 14:11:43 -0700 Subject: s3 onefs: update the onefs module to be compliant with stat_ex --- source3/modules/onefs.h | 13 ++++++ source3/modules/onefs_acl.c | 5 ++- source3/modules/onefs_dir.c | 12 ++++-- source3/modules/onefs_notify.c | 8 ++-- source3/modules/onefs_open.c | 38 ++++++++--------- source3/modules/onefs_streams.c | 83 ++++++++++++++++++------------------ source3/modules/onefs_system.c | 94 +++++++++++++++++++++++++++++++++++++++++ source3/modules/vfs_onefs.c | 16 +++---- 8 files changed, 192 insertions(+), 77 deletions(-) diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index 9d63021f42..70f90b5cd5 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -170,4 +170,17 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, size_t count); +void init_stat_ex_from_onefs_stat(struct stat_ex *dst, const struct stat *src); + +int onefs_sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf); + +int onefs_sys_fstat(int fd, SMB_STRUCT_STAT *sbuf); + +int onefs_sys_fstat_at(int base_fd, const char *fname, SMB_STRUCT_STAT *sbuf, + int flags); + +int onefs_sys_lstat(const char *fname, SMB_STRUCT_STAT *sbuf); + + + #endif /* _ONEFS_H */ diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index d66e5d65fa..81bdfd26cc 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -393,7 +393,7 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd) if (error) return false; - if ((sbuf.st_flags & SF_HASNTFSACL) != 0) { + if ((sbuf.st_ex_flags & SF_HASNTFSACL) != 0) { DEBUG(10, ("Did not canonicalize ACLs because a " "Windows ACL set was found for file %s\n", fsp->fsp_name)); @@ -540,7 +540,8 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd) } /* Only continue if this is a synthetic ACL and a directory. */ - if (S_ISDIR(sbuf.st_mode) && (sbuf.st_flags & SF_HASNTFSACL) == 0) { + if (S_ISDIR(sbuf.st_ex_mode) && + (sbuf.st_ex_flags & SF_HASNTFSACL) == 0) { struct ifs_ace new_aces[6]; struct ifs_ace *old_aces; int i, num_aces_to_add = 0; diff --git a/source3/modules/onefs_dir.c b/source3/modules/onefs_dir.c index 47da33fff1..2ab8b86771 100644 --- a/source3/modules/onefs_dir.c +++ b/source3/modules/onefs_dir.c @@ -43,7 +43,7 @@ #define RDP_DIRENTRIES_SIZE ((size_t)(RDP_BATCH_SIZE * sizeof(struct dirent))) static char *rdp_direntries = NULL; -static SMB_STRUCT_STAT *rdp_stats = NULL; +static struct stat *rdp_stats = NULL; static uint64_t *rdp_cookies = NULL; struct rdp_dir_state { @@ -113,7 +113,7 @@ rdp_init(struct rdp_dir_state *dsp) if (!rdp_stats) { rdp_stats = - SMB_MALLOC(RDP_BATCH_SIZE * sizeof(SMB_STRUCT_STAT)); + SMB_MALLOC(RDP_BATCH_SIZE * sizeof(struct stat)); if (!rdp_stats) return ENOMEM; } @@ -367,11 +367,15 @@ onefs_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, /* Return an entry from cache */ ret_direntp = ((SMB_STRUCT_DIRENT *)dsp->direntries_cursor); if (sbuf) { - *sbuf = rdp_stats[dsp->stat_cursor]; + struct stat onefs_sbuf; + + onefs_sbuf = rdp_stats[dsp->stat_cursor]; + init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf); + /* readdirplus() sets st_ino field to 0, if it was * unable to retrieve stat information for that * particular directory entry. */ - if (sbuf->st_ino == 0) + if (sbuf->st_ex_ino == 0) SET_STAT_INVALID(*sbuf); } diff --git a/source3/modules/onefs_notify.c b/source3/modules/onefs_notify.c index 3455afd4ab..0447d0c03e 100644 --- a/source3/modules/onefs_notify.c +++ b/source3/modules/onefs_notify.c @@ -630,21 +630,21 @@ onefs_notify_watch(vfs_handle_struct *vfs_handle, } /* Get LIN for directory */ - if (sys_fstat(e->dir_fd, &sbuf)) { + if (onefs_sys_fstat(e->dir_fd, &sbuf)) { DEBUG(0, ("stat on directory fd failed: %s\n", strerror(errno))); status = map_nt_error_from_unix(errno); goto err; } - if (sbuf.st_ino == 0) { + if (sbuf.st_ex_ino == 0) { DEBUG(0, ("0 LIN found!\n")); goto err; } wc->ctx = ctx; wc->watch_fd = e->dir_fd; - wc->watch_lin = sbuf.st_ino; + wc->watch_lin = sbuf.st_ex_ino; wc->ifs_event_fd = ifs_event_fd; wc->ifs_filter = ifs_filter; wc->smb_filter = smb_filter; @@ -669,7 +669,7 @@ onefs_notify_watch(vfs_handle_struct *vfs_handle, "ifs_filter=0x%x, watch_tree=%d, ifs_event_fd=%d, " "dir_fd=%d, dir_lin=0x%llx\n", e->path, smb_filter, ifs_filter, watch_tree, - ifs_event_fd, e->dir_fd, sbuf.st_ino)); + ifs_event_fd, e->dir_fd, sbuf.st_ex_ino)); return NT_STATUS_OK; diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index 6cfa24f9f6..21c5d51f90 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -148,7 +148,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp, * open flags. JRA. */ - if (file_existed && S_ISFIFO(psbuf->st_mode)) { + if (file_existed && S_ISFIFO(psbuf->st_ex_mode)) { local_flags |= O_NONBLOCK; } #endif @@ -289,13 +289,13 @@ static NTSTATUS onefs_open_file(files_struct *fsp, * so catch a directory open and return an EISDIR. JRA. */ - if(S_ISDIR(psbuf->st_mode)) { + if(S_ISDIR(psbuf->st_ex_mode)) { fd_close(fsp); errno = EISDIR; return NT_STATUS_FILE_IS_A_DIRECTORY; } - fsp->mode = psbuf->st_mode; + fsp->mode = psbuf->st_ex_mode; fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf); fsp->vuid = req ? req->vuid : UID_FIELD_INVALID; fsp->file_pid = req ? req->smbpid : 0; @@ -661,7 +661,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, "FILE_CREATE requested for file %s " "and file already exists.\n", fname)); - if (S_ISDIR(psbuf->st_mode)) { + if (S_ISDIR(psbuf->st_ex_mode)) { errno = EISDIR; } else { errno = EEXIST; @@ -687,13 +687,13 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, (create_disposition == FILE_OVERWRITE_IF))) { if (!open_match_attributes(conn, fname, existing_dos_attributes, - new_dos_attributes, psbuf->st_mode, + new_dos_attributes, psbuf->st_ex_mode, unx_mode, &new_unx_mode)) { DEBUG(5, ("onefs_open_file_ntcreate: attributes " "missmatch for file %s (%x %x) (0%o, 0%o)\n", fname, existing_dos_attributes, new_dos_attributes, - (unsigned int)psbuf->st_mode, + (unsigned int)psbuf->st_ex_mode, (unsigned int)unx_mode )); errno = EACCES; return NT_STATUS_ACCESS_DENIED; @@ -816,7 +816,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, } if (file_existed) { - struct timespec old_write_time = get_mtimespec(psbuf); + struct timespec old_write_time = psbuf->st_ex_mtime; id = vfs_file_id_from_sbuf(conn, psbuf); lck = get_share_mode_lock(talloc_tos(), id, @@ -900,7 +900,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, struct deferred_open_record state; struct timespec old_write_time; - old_write_time = get_mtimespec(psbuf); + old_write_time = psbuf->st_ex_mtime; DEBUG(3, ("Someone created file %s with an " "oplock after we looked: Retrying\n", @@ -1089,7 +1089,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, } if (!file_existed) { - struct timespec old_write_time = get_mtimespec(psbuf); + struct timespec old_write_time = psbuf->st_ex_mtime; /* * Deal with the race condition where two smbd's detect the * file doesn't exist and do the create at the same time. One @@ -1267,7 +1267,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, * May be necessary depending on acl policies. */ if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf) - && (psbuf->st_flags & SF_HASNTFSACL))) { + && (psbuf->st_ex_flags & SF_HASNTFSACL))) { int saved_errno = errno; /* We might get ENOSYS in the next * call.. */ @@ -1495,7 +1495,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn, return map_nt_error_from_unix(errno); } - if (!S_ISDIR(psbuf->st_mode)) { + if (!S_ISDIR(psbuf->st_ex_mode)) { DEBUG(0, ("Directory just '%s' created is not a " "directory\n", fname)); return NT_STATUS_ACCESS_DENIED; @@ -1509,9 +1509,9 @@ static NTSTATUS onefs_open_directory(connection_struct *conn, * parent dir. */ if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && - (mode & ~psbuf->st_mode)) { - SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode | - (mode & ~psbuf->st_mode))); + (mode & ~psbuf->st_ex_mode)) { + SMB_VFS_CHMOD(conn, fname, (psbuf->st_ex_mode | + (mode & ~psbuf->st_ex_mode))); } } @@ -1533,7 +1533,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn, } /* Setup the files_struct for it. */ - fsp->mode = psbuf->st_mode; + fsp->mode = psbuf->st_ex_mode; fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf); fsp->vuid = req ? req->vuid : UID_FIELD_INVALID; fsp->file_pid = req ? req->smbpid : 0; @@ -1556,7 +1556,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn, string_set(&fsp->fsp_name,fname); - mtimespec = get_mtimespec(psbuf); + mtimespec = psbuf->st_ex_mtime; /* * Still set the samba share mode lock for correct delete-on-close @@ -1904,7 +1904,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn, } } - if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) { + if (!fsp->is_directory && S_ISDIR(sbuf.st_ex_mode)) { status = NT_STATUS_ACCESS_DENIED; goto fail; } @@ -1912,7 +1912,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn, /* Save the requested allocation size. */ if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) { if (allocation_size - && (allocation_size > sbuf.st_size)) { + && (allocation_size > sbuf.st_ex_size)) { fsp->initial_allocation_size = smb_roundup( fsp->conn, allocation_size); if (fsp->is_directory) { @@ -1927,7 +1927,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn, } } else { fsp->initial_allocation_size = smb_roundup( - fsp->conn, (uint64_t)sbuf.st_size); + fsp->conn, (uint64_t)sbuf.st_ex_size); } } diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 05b36d7d3c..284e199fc5 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -222,81 +222,84 @@ static void merge_stat(SMB_STRUCT_STAT *stream_sbuf, { int dos_flags = (UF_DOS_NOINDEX | UF_DOS_ARCHIVE | UF_DOS_HIDDEN | UF_DOS_RO | UF_DOS_SYSTEM); - stream_sbuf->st_mtime = base_sbuf->st_mtime; - stream_sbuf->st_ctime = base_sbuf->st_ctime; - stream_sbuf->st_atime = base_sbuf->st_atime; - stream_sbuf->st_flags &= ~dos_flags; - stream_sbuf->st_flags |= base_sbuf->st_flags & dos_flags; + stream_sbuf->st_ex_mtime = base_sbuf->st_ex_mtime; + stream_sbuf->st_ex_ctime = base_sbuf->st_ex_ctime; + stream_sbuf->st_ex_atime = base_sbuf->st_ex_atime; + stream_sbuf->st_ex_flags &= ~dos_flags; + stream_sbuf->st_ex_flags |= base_sbuf->st_ex_flags & dos_flags; } /* fake timestamps */ -static void onefs_adjust_stat_time(vfs_handle_struct *handle, const char *fname, - SMB_STRUCT_STAT *sbuf) +static void onefs_adjust_stat_time(struct connection_struct *conn, + const char *fname, SMB_STRUCT_STAT *sbuf) { struct onefs_vfs_share_config cfg; struct timeval tv_now = {0, 0}; bool static_mtime = False; bool static_atime = False; - if (!onefs_get_config(SNUM(handle->conn), + if (!onefs_get_config(SNUM(conn), ONEFS_VFS_CONFIG_FAKETIMESTAMPS, &cfg)) { return; } - if (IS_MTIME_STATIC_PATH(handle->conn, &cfg, fname)) { - sbuf->st_mtime = sbuf->st_birthtime; + if (IS_MTIME_STATIC_PATH(conn, &cfg, fname)) { + sbuf->st_ex_mtime = sbuf->st_ex_btime; static_mtime = True; } - if (IS_ATIME_STATIC_PATH(handle->conn, &cfg, fname)) { - sbuf->st_atime = sbuf->st_birthtime; + if (IS_ATIME_STATIC_PATH(conn, &cfg, fname)) { + sbuf->st_ex_atime = sbuf->st_ex_btime; static_atime = True; } - if (IS_CTIME_NOW_PATH(handle->conn, &cfg, fname)) { + if (IS_CTIME_NOW_PATH(conn, &cfg, fname)) { if (cfg.ctime_slop < 0) { - sbuf->st_birthtime = INT_MAX - 1; + sbuf->st_ex_btime.tv_sec = INT_MAX - 1; } else { GetTimeOfDay(&tv_now); - sbuf->st_birthtime = tv_now.tv_sec + cfg.ctime_slop; + sbuf->st_ex_btime.tv_sec = tv_now.tv_sec + + cfg.ctime_slop; } } - if (!static_mtime && IS_MTIME_NOW_PATH(handle->conn,&cfg,fname)) { + if (!static_mtime && IS_MTIME_NOW_PATH(conn,&cfg,fname)) { if (cfg.mtime_slop < 0) { - sbuf->st_mtime = INT_MAX - 1; + sbuf->st_ex_mtime.tv_sec = INT_MAX - 1; } else { if (tv_now.tv_sec == 0) GetTimeOfDay(&tv_now); - sbuf->st_mtime = tv_now.tv_sec + cfg.mtime_slop; + sbuf->st_ex_mtime.tv_sec = tv_now.tv_sec + + cfg.mtime_slop; } } - if (!static_atime && IS_ATIME_NOW_PATH(handle->conn,&cfg,fname)) { + if (!static_atime && IS_ATIME_NOW_PATH(conn,&cfg,fname)) { if (cfg.atime_slop < 0) { - sbuf->st_atime = INT_MAX - 1; + sbuf->st_ex_atime.tv_sec = INT_MAX - 1; } else { if (tv_now.tv_sec == 0) GetTimeOfDay(&tv_now); - sbuf->st_atime = tv_now.tv_sec + cfg.atime_slop; + sbuf->st_ex_atime.tv_sec = tv_now.tv_sec + + cfg.atime_slop; } } } -static int stat_stream(vfs_handle_struct *handle, const char *base, +static int stat_stream(struct connection_struct *conn, const char *base, const char *stream, SMB_STRUCT_STAT *sbuf, int flags) { SMB_STRUCT_STAT base_sbuf; int base_fd = -1, dir_fd, ret, saved_errno; - dir_fd = get_stream_dir_fd(handle->conn, base, &base_fd); + dir_fd = get_stream_dir_fd(conn, base, &base_fd); if (dir_fd < 0) { return -1; } /* Stat the stream. */ - ret = enc_fstatat(dir_fd, stream, ENC_DEFAULT, sbuf, flags); + ret = onefs_sys_fstat_at(dir_fd, stream, sbuf, flags); if (ret != -1) { /* Now stat the base file and merge the results. */ - ret = sys_fstat(base_fd, &base_sbuf); + ret = onefs_sys_fstat(base_fd, &base_sbuf); if (ret != -1) { merge_stat(sbuf, &base_sbuf); } @@ -322,15 +325,15 @@ int onefs_stat(vfs_handle_struct *handle, const char *path, return ret; if (!is_stream) { - ret = SMB_VFS_NEXT_STAT(handle, path, sbuf); + ret = onefs_sys_stat(path, sbuf); } else if (!stream) { /* If it's the ::$DATA stream just stat the base file name. */ - ret = SMB_VFS_NEXT_STAT(handle, base, sbuf); + ret = onefs_sys_stat(base, sbuf); } else { - ret = stat_stream(handle, base, stream, sbuf, 0); + ret = stat_stream(handle->conn, base, stream, sbuf, 0); } - onefs_adjust_stat_time(handle, path, sbuf); + onefs_adjust_stat_time(handle->conn, path, sbuf); return ret; } @@ -341,20 +344,20 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp, int ret; /* Stat the stream, by calling next_fstat on the stream's fd. */ - ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); + ret = onefs_sys_fstat(fsp->fh->fd, sbuf); if (ret == -1) { return ret; } /* Stat the base file and merge the results. */ if (fsp != NULL && fsp->base_fsp != NULL) { - ret = sys_fstat(fsp->base_fsp->fh->fd, &base_sbuf); + ret = onefs_sys_fstat(fsp->base_fsp->fh->fd, &base_sbuf); if (ret != -1) { merge_stat(sbuf, &base_sbuf); } } - onefs_adjust_stat_time(handle, fsp->fsp_name, sbuf); + onefs_adjust_stat_time(handle->conn, fsp->fsp_name, sbuf); return ret; } @@ -371,16 +374,16 @@ int onefs_lstat(vfs_handle_struct *handle, const char *path, return ret; if (!is_stream) { - ret = SMB_VFS_NEXT_LSTAT(handle, path, sbuf); + ret = onefs_sys_lstat(path, sbuf); } else if (!stream) { /* If it's the ::$DATA stream just stat the base file name. */ - ret = SMB_VFS_NEXT_LSTAT(handle, base, sbuf); + ret = onefs_sys_lstat(base, sbuf); } else { - ret = stat_stream(handle, base, stream, sbuf, + ret = stat_stream(handle->conn, base, stream, sbuf, AT_SYMLINK_NOFOLLOW); } - onefs_adjust_stat_time(handle, path, sbuf); + onefs_adjust_stat_time(handle->conn, path, sbuf); return ret; } @@ -614,7 +617,7 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp, if (!add_one_stream(state->mem_ctx, &state->num_streams, &state->streams, - dp->d_name, stream_sbuf.st_size, + dp->d_name, stream_sbuf.st_ex_size, SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &stream_sbuf))) { state->status = NT_STATUS_NO_MEMORY; @@ -677,10 +680,10 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle, } /* Add the default stream. */ - if (S_ISREG(sbuf.st_mode)) { + if (S_ISREG(sbuf.st_ex_mode)) { if (!add_one_stream(mem_ctx, &state.num_streams, &state.streams, - "", sbuf.st_size, + "", sbuf.st_ex_size, SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf))) { return NT_STATUS_NO_MEMORY; @@ -692,7 +695,7 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle, state.status = NT_STATUS_OK; /* If there are more streams, add them too. */ - if (sbuf.st_flags & UF_HASADS) { + if (sbuf.st_ex_flags & UF_HASADS) { status = walk_onefs_streams(handle->conn, fsp, fname, &state, &sbuf); diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 3e51c6cd85..d2f853f9ee 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -666,3 +666,97 @@ out: return ret; } + +void init_stat_ex_from_onefs_stat(struct stat_ex *dst, const struct stat *src) +{ + ZERO_STRUCT(*dst); + + dst->st_ex_dev = src->st_dev; + dst->st_ex_ino = src->st_ino; + dst->st_ex_mode = src->st_mode; + dst->st_ex_nlink = src->st_nlink; + dst->st_ex_uid = src->st_uid; + dst->st_ex_gid = src->st_gid; + dst->st_ex_rdev = src->st_rdev; + dst->st_ex_size = src->st_size; + dst->st_ex_atime = src->st_atimespec; + dst->st_ex_mtime = src->st_mtimespec; + dst->st_ex_ctime = src->st_ctimespec; + dst->st_ex_btime = src->st_birthtimespec; + dst->st_ex_blksize = src->st_blksize; + dst->st_ex_blocks = src->st_blocks; + + dst->st_ex_flags = src->st_flags; + + dst->vfs_private = src->st_snapid; +} + +int onefs_sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf) +{ + int ret; + struct stat onefs_sbuf; + + ret = stat(fname, &onefs_sbuf); + + if (ret == 0) { + /* we always want directories to appear zero size */ + if (S_ISDIR(onefs_sbuf.st_mode)) { + onefs_sbuf.st_size = 0; + } + init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf); + } + return ret; +} + +int onefs_sys_fstat(int fd, SMB_STRUCT_STAT *sbuf) +{ + int ret; + struct stat onefs_sbuf; + + ret = fstat(fd, &onefs_sbuf); + + if (ret == 0) { + /* we always want directories to appear zero size */ + if (S_ISDIR(onefs_sbuf.st_mode)) { + onefs_sbuf.st_size = 0; + } + init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf); + } + return ret; +} + +int onefs_sys_fstat_at(int base_fd, const char *fname, SMB_STRUCT_STAT *sbuf, + int flags) +{ + int ret; + struct stat onefs_sbuf; + + ret = enc_fstatat(base_fd, fname, ENC_DEFAULT, &onefs_sbuf, flags); + + if (ret == 0) { + /* we always want directories to appear zero size */ + if (S_ISDIR(onefs_sbuf.st_mode)) { + onefs_sbuf.st_size = 0; + } + init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf); + } + return ret; +} + +int onefs_sys_lstat(const char *fname, SMB_STRUCT_STAT *sbuf) +{ + int ret; + struct stat onefs_sbuf; + + ret = lstat(fname, &onefs_sbuf); + + if (ret == 0) { + /* we always want directories to appear zero size */ + if (S_ISDIR(onefs_sbuf.st_mode)) { + onefs_sbuf.st_size = 0; + } + init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf); + } + return ret; +} + diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index e4a0febbec..7414f16cf9 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -88,7 +88,7 @@ static uint64_t onefs_get_alloc_size(struct vfs_handle_struct *handle, START_PROFILE(syscall_get_alloc_size); - if(S_ISDIR(sbuf->st_mode)) { + if(S_ISDIR(sbuf->st_ex_mode)) { result = 0; goto out; } @@ -115,9 +115,9 @@ static struct file_id onefs_file_id_create(struct vfs_handle_struct *handle, * blob */ ZERO_STRUCT(key); - key.devid = sbuf->st_dev; - key.inode = sbuf->st_ino; - key.extid = sbuf->st_snapid; + key.devid = sbuf->st_ex_dev; + key.inode = sbuf->st_ex_ino; + key.extid = sbuf->vfs_private; return key; } @@ -152,7 +152,7 @@ static int onefs_get_real_filename(vfs_handle_struct *handle, const char *path, const char *name, TALLOC_CTX *mem_ctx, char **found_name) { - SMB_STRUCT_STAT sb; + struct stat sb; struct connection_struct *conn = handle->conn; struct stat_extra se; int result; @@ -278,11 +278,11 @@ static vfs_op_tuple onefs_ops[] = { {SMB_VFS_OP(onefs_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(onefs_stat), SMB_VFS_OP_STAT, - SMB_VFS_LAYER_TRANSPARENT}, + SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_fstat), SMB_VFS_OP_FSTAT, - SMB_VFS_LAYER_TRANSPARENT}, + SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_lstat), SMB_VFS_OP_LSTAT, - SMB_VFS_LAYER_TRANSPARENT}, + SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_get_alloc_size), SMB_VFS_OP_GET_ALLOC_SIZE, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_unlink), SMB_VFS_OP_UNLINK, -- cgit From 9df85a93746d2de0c68c50d634a04e957e8b2c0d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 28 May 2009 16:15:09 -0700 Subject: Make cli_posix_chown()/cli_posix_chmod() async. Jeremy. --- source3/client/client.c | 4 +- source3/include/proto.h | 20 +++- source3/libsmb/clifile.c | 260 ++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 233 insertions(+), 51 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 7e98dea91c..0852652725 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2872,7 +2872,7 @@ static int cmd_chmod(void) return 1; } - if (!cli_unix_chmod(targetcli, targetname, mode)) { + if (!NT_STATUS_IS_OK(cli_posix_chmod(targetcli, targetname, mode))) { d_printf("%s chmod file %s 0%o\n", cli_errstr(targetcli), src, (unsigned int)mode); return 1; @@ -3292,7 +3292,7 @@ static int cmd_chown(void) return 1; } - if (!cli_unix_chown(targetcli, targetname, uid, gid)) { + if (!NT_STATUS_IS_OK(cli_posix_chown(targetcli, targetname, uid, gid))) { d_printf("%s chown file %s uid=%d, gid=%d\n", cli_errstr(targetcli), src, (int)uid, (int)gid); return 1; diff --git a/source3/include/proto.h b/source3/include/proto.h index af68ae74a0..4713bd713a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2383,8 +2383,24 @@ NTSTATUS cli_posix_stat_recv(struct tevent_req *req, NTSTATUS cli_posix_stat(struct cli_state *cli, const char *fname, SMB_STRUCT_STAT *sbuf); -bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode); -bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid); +struct tevent_req *cli_posix_chmod_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + mode_t mode); +NTSTATUS cli_posix_chmod_recv(struct tevent_req *req); +NTSTATUS cli_posix_chmod(struct cli_state *cli, const char *fname, mode_t mode); +struct tevent_req *cli_posix_chown_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uid_t uid, + gid_t gid); +NTSTATUS cli_posix_chown_recv(struct tevent_req *req); +NTSTATUS cli_posix_chown(struct cli_state *cli, + const char *fname, + uid_t uid, + gid_t gid); struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 4c5dc3bd19..f73428ee21 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -946,81 +946,247 @@ NTSTATUS cli_posix_stat(struct cli_state *cli, Chmod or chown a file internal (UNIX extensions). ****************************************************************************/ -static bool cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32_t mode, uint32_t uid, uint32_t gid) +struct ch_state { + uint16_t setup; + uint8_t *param; + uint8_t *data; +}; + +static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq) { - unsigned int data_len = 0; - unsigned int param_len = 0; - uint16_t setup = TRANSACT2_SETPATHINFO; - size_t nlen = 2*(strlen(fname)+1); - char *param; - char data[100]; - char *rparam=NULL, *rdata=NULL; - char *p; + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct ch_state *state = tevent_req_data(req, struct ch_state); + NTSTATUS status; - param = SMB_MALLOC_ARRAY(char, 6+nlen+2); - if (!param) { - return false; + status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } - memset(param, '\0', 6); - memset(data, 0, sizeof(data)); + tevent_req_done(req); +} - SSVAL(param,0,SMB_SET_FILE_UNIX_BASIC); - p = ¶m[6]; +static struct tevent_req *cli_posix_chown_chmod_internal_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uint32_t mode, + uint32_t uid, + uint32_t gid) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct ch_state *state = NULL; - p += clistr_push(cli, p, fname, nlen, STR_TERMINATE); - param_len = PTR_DIFF(p, param); + req = tevent_req_create(mem_ctx, &state, struct ch_state); + if (req == NULL) { + return NULL; + } - memset(data, 0xff, 40); /* Set all sizes/times to no change. */ + /* Setup setup word. */ + SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO); - SIVAL(data,40,uid); - SIVAL(data,48,gid); - SIVAL(data,84,mode); + /* Setup param array. */ + state->param = talloc_array(state, uint8_t, 6); + if (tevent_req_nomem(state->param, req)) { + return tevent_req_post(req, ev); + } + memset(state->param, '\0', 6); + SSVAL(state->param,0,SMB_SET_FILE_UNIX_BASIC); - data_len = 100; + state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname, + strlen(fname)+1, NULL); - if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ - )) { - SAFE_FREE(param); - return False; + if (tevent_req_nomem(state->param, req)) { + return tevent_req_post(req, ev); } - SAFE_FREE(param); - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return false; + /* Setup data array. */ + state->data = talloc_array(state, uint8_t, 100); + if (tevent_req_nomem(state->data, req)) { + return tevent_req_post(req, ev); } + memset(state->data, 0xff, 40); /* Set all sizes/times to no change. */ + memset(&state->data[40], '\0', 60); + SIVAL(state->data,40,uid); + SIVAL(state->data,48,gid); + SIVAL(state->data,84,mode); - SAFE_FREE(rdata); - SAFE_FREE(rparam); + subreq = cli_trans_send(state, /* mem ctx. */ + ev, /* event ctx. */ + cli, /* cli_state. */ + SMBtrans2, /* cmd. */ + NULL, /* pipe name. */ + -1, /* fid. */ + 0, /* function. */ + 0, /* flags. */ + &state->setup, /* setup. */ + 1, /* num setup uint16_t words. */ + 0, /* max returned setup. */ + state->param, /* param. */ + talloc_get_size(state->param), /* num param. */ + 2, /* max returned param. */ + state->data, /* data. */ + talloc_get_size(state->data), /* num data. */ + 0); /* max returned data. */ - return true; + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_posix_chown_chmod_internal_done, req); + return req; } /**************************************************************************** chmod a file (UNIX extensions). ****************************************************************************/ -bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) +struct tevent_req *cli_posix_chmod_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + mode_t mode) +{ + return cli_posix_chown_chmod_internal_send(mem_ctx, ev, cli, + fname, + unix_perms_to_wire(mode), + SMB_UID_NO_CHANGE, + SMB_GID_NO_CHANGE); +} + +NTSTATUS cli_posix_chmod_recv(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_posix_chmod(struct cli_state *cli, const char *fname, mode_t mode) { - return cli_unix_chmod_chown_internal(cli, fname, - unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE); + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_posix_chmod_send(frame, + ev, + cli, + fname, + mode); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_chmod_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** chown a file (UNIX extensions). ****************************************************************************/ -bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid) +struct tevent_req *cli_posix_chown_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uid_t uid, + gid_t gid) +{ + return cli_posix_chown_chmod_internal_send(mem_ctx, ev, cli, + fname, + SMB_MODE_NO_CHANGE, + (uint32_t)uid, + (uint32_t)gid); +} + +NTSTATUS cli_posix_chown_recv(struct tevent_req *req) { - return cli_unix_chmod_chown_internal(cli, fname, - SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_posix_chown(struct cli_state *cli, + const char *fname, + uid_t uid, + gid_t gid) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_posix_chown_send(frame, + ev, + cli, + fname, + uid, + gid); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_chown_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** -- cgit From 2e573a7cf4c2c4f75182d2266c998ff13edce5a5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 May 2009 10:34:00 +1000 Subject: Fix incorrect RID for KRBTGT. (was incorectly 514, should be 502) Requires recompile of source4/kdc/* Found by Andrew Kroeger Andrew Bartlett --- librpc/idl/security.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl index 9e47ff45fc..941883f644 100644 --- a/librpc/idl/security.idl +++ b/librpc/idl/security.idl @@ -224,9 +224,9 @@ interface security const int DOMAIN_RID_LOGON = 9; const int DOMAIN_RID_ADMINISTRATOR = 500; const int DOMAIN_RID_GUEST = 501; + const int DOMAIN_RID_KRBTGT = 502; const int DOMAIN_RID_ADMINS = 512; const int DOMAIN_RID_USERS = 513; - const int DOMAIN_RID_KRBTGT = 514; const int DOMAIN_RID_DOMAIN_MEMBERS = 515; const int DOMAIN_RID_DCS = 516; const int DOMAIN_RID_CERT_ADMINS = 517; -- cgit From 340c690d1731fe638bd6afe1fe38c7a7977b9687 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 May 2009 10:34:00 +1000 Subject: Fix incorrect RID for KRBTGT. (was incorectly 514, should be 502) Requires recompile of source4/kdc/* Found by Andrew Kroeger Andrew Bartlett --- librpc/gen_ndr/security.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/gen_ndr/security.h b/librpc/gen_ndr/security.h index 16635f0bb8..9db2108f82 100644 --- a/librpc/gen_ndr/security.h +++ b/librpc/gen_ndr/security.h @@ -124,9 +124,9 @@ #define DOMAIN_RID_LOGON ( 9 ) #define DOMAIN_RID_ADMINISTRATOR ( 500 ) #define DOMAIN_RID_GUEST ( 501 ) +#define DOMAIN_RID_KRBTGT ( 502 ) #define DOMAIN_RID_ADMINS ( 512 ) #define DOMAIN_RID_USERS ( 513 ) -#define DOMAIN_RID_KRBTGT ( 514 ) #define DOMAIN_RID_DOMAIN_MEMBERS ( 515 ) #define DOMAIN_RID_DCS ( 516 ) #define DOMAIN_RID_CERT_ADMINS ( 517 ) -- cgit From 37e09f26dc8acc47d4ea201923b05c24610d0060 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 May 2009 10:42:28 +1000 Subject: s4:torture Make the RPC-SAMR-PWDLASTET more efficient By using SamLogonEx we avoid setting up the credentials chain for each request. (Needs to be pushed further up the stack, to only connect to NETLOGON once). Andrew Bartlett --- source4/torture/rpc/samr.c | 92 ++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 92ce66fef2..d13c547a2b 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -2673,21 +2673,20 @@ static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p, return true; } -static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx, - struct cli_credentials *machine_credentials, - struct cli_credentials *test_credentials, - struct netlogon_creds_CredentialState *creds, - NTSTATUS expected_result) +static bool test_SamLogon(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct cli_credentials *test_credentials, + NTSTATUS expected_result) { NTSTATUS status; - struct netr_LogonSamLogon r; - struct netr_Authenticator auth, auth2; + struct netr_LogonSamLogonEx r; union netr_LogonLevel logon; union netr_Validation validation; uint8_t authoritative; struct netr_NetworkInfo ninfo; DATA_BLOB names_blob, chal, lm_resp, nt_resp; int flags = CLI_CRED_NTLM_AUTH; + uint32_t samlogon_flags = 0; if (lp_client_lanman_auth(tctx->lp_ctx)) { flags |= CLI_CRED_LANMAN_AUTH; @@ -2706,8 +2705,8 @@ static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *t chal = data_blob_const(ninfo.challenge, sizeof(ninfo.challenge)); - names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials), - cli_credentials_get_domain(machine_credentials)); + names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials), + cli_credentials_get_domain(test_credentials)); status = cli_credentials_get_ntlm_response(test_credentials, tctx, &flags, @@ -2728,56 +2727,34 @@ static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *t MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT; ninfo.identity_info.logon_id_low = 0; ninfo.identity_info.logon_id_high = 0; - ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials); + ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials); logon.network = &ninfo; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); - r.in.computer_name = cli_credentials_get_workstation(machine_credentials); - r.in.credential = &auth; - r.in.return_authenticator = &auth2; - r.in.logon_level = 2; + r.in.computer_name = cli_credentials_get_workstation(test_credentials); + r.in.logon_level = NetlogonNetworkInformation; r.in.logon = &logon; + r.in.flags = &samlogon_flags; + r.out.flags = &samlogon_flags; r.out.validation = &validation; r.out.authoritative = &authoritative; d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string); - ZERO_STRUCT(auth2); - netlogon_creds_client_authenticator(creds, &auth); - - r.in.validation_level = 2; + r.in.validation_level = 6; - status = dcerpc_netr_LogonSamLogon(p, tctx, &r); + status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { - torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed"); + torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed"); return true; } else { - torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed"); + torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed"); } - torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred), - "Credential chaining failed"); - return true; } -static bool test_SamLogon(struct torture_context *tctx, - struct dcerpc_pipe *p, - struct cli_credentials *machine_credentials, - struct cli_credentials *test_credentials, - NTSTATUS expected_result) -{ - struct netlogon_creds_CredentialState *creds; - - if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) { - return false; - } - - return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials, - creds, expected_result); -} - static bool test_SamLogon_with_creds(struct torture_context *tctx, struct dcerpc_pipe *p, struct cli_credentials *machine_creds, @@ -2791,19 +2768,18 @@ static bool test_SamLogon_with_creds(struct torture_context *tctx, test_credentials = cli_credentials_init(tctx); cli_credentials_set_workstation(test_credentials, - TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED); + cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED); cli_credentials_set_domain(test_credentials, - lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED); + cli_credentials_get_domain(machine_creds), CRED_SPECIFIED); cli_credentials_set_username(test_credentials, acct_name, CRED_SPECIFIED); cli_credentials_set_password(test_credentials, password, CRED_SPECIFIED); - cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC); - printf("testing samlogon as %s@%s password: %s\n", - acct_name, TEST_ACCOUNT_NAME_PWD, password); + printf("testing samlogon as %s password: %s\n", + acct_name, password); - if (!test_SamLogon(tctx, p, machine_creds, test_credentials, + if (!test_SamLogon(tctx, p, test_credentials, expected_samlogon_result)) { torture_warning(tctx, "new password did not work\n"); ret = false; @@ -2886,8 +2862,9 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p, struct cli_credentials *machine_credentials) { int s = 0, q = 0, f = 0, l = 0, z = 0; + struct dcerpc_binding *b; bool ret = true; - int delay = 500000; + int delay = 50000; bool set_levels[] = { false, true }; bool query_levels[] = { false, true }; uint32_t levels[] = { 18, 21, 23, 24, 25, 26 }; @@ -2915,9 +2892,26 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p, delay); } - status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon); + status = torture_rpc_binding(tctx, &b); if (!NT_STATUS_IS_OK(status)) { - return false; + ret = false; + return ret; + } + + /* We have to use schannel, otherwise the SamLogonEx fails + * with INTERNAL_ERROR */ + + b->flags &= ~DCERPC_AUTH_OPTIONS; + b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128; + + status = dcerpc_pipe_connect_b(tctx, &np, b, + &ndr_table_netlogon, + machine_credentials, tctx->ev, tctx->lp_ctx); + + if (!NT_STATUS_IS_OK(status)) { + d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status)); + ret = false; + return ret; } /* set to 1 to enable testing for all possible opcode -- cgit From e8ea854f0262ea2a1449695a0c70bea40bfbb872 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 May 2009 11:44:44 +1000 Subject: s4:client Match Samba3 and remove smbmount from the distribution --- source4/client/smbmnt.c | 306 --------------- source4/client/smbmount.c | 942 --------------------------------------------- source4/client/smbumount.c | 186 --------- 3 files changed, 1434 deletions(-) delete mode 100644 source4/client/smbmnt.c delete mode 100644 source4/client/smbmount.c delete mode 100644 source4/client/smbumount.c diff --git a/source4/client/smbmnt.c b/source4/client/smbmnt.c deleted file mode 100644 index 0d619a88fe..0000000000 --- a/source4/client/smbmnt.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * smbmnt.c - * - * Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke - * extensively modified by Tridge - * - */ - -#include "includes.h" - -#include -#include - -#include -#include -#include -#include -#include - -#ifndef MS_MGC_VAL -/* This may look strange but MS_MGC_VAL is what we are looking for and - is what we need from under libc systems and is - provided in standard includes on glibc systems. So... We - switch on what we need... */ -#include -#endif - -static uid_t mount_uid; -static gid_t mount_gid; -static int mount_ro; -static uint_t mount_fmask; -static uint_t mount_dmask; -static int user_mount; -static char *options; - -static void -help(void) -{ - printf("\n"); - printf("Usage: smbmnt mount-point [options]\n"); - printf("Version %s\n\n",VERSION); - printf("-s share share name on server\n" - "-r mount read-only\n" - "-u uid mount as uid\n" - "-g gid mount as gid\n" - "-f mask permission mask for files\n" - "-d mask permission mask for directories\n" - "-o options name=value, list of options\n" - "-h print this help text\n"); -} - -static int -parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share) -{ - int opt; - - while ((opt = getopt (argc, argv, "s:u:g:rf:d:o:")) != EOF) - { - switch (opt) - { - case 's': - *share = optarg; - break; - case 'u': - if (!user_mount) { - mount_uid = strtol(optarg, NULL, 0); - } - break; - case 'g': - if (!user_mount) { - mount_gid = strtol(optarg, NULL, 0); - } - break; - case 'r': - mount_ro = 1; - break; - case 'f': - mount_fmask = strtol(optarg, NULL, 8); - break; - case 'd': - mount_dmask = strtol(optarg, NULL, 8); - break; - case 'o': - options = optarg; - break; - default: - return -1; - } - } - return 0; - -} - -static char * -fullpath(const char *p) -{ - char path[MAXPATHLEN]; - - if (strlen(p) > MAXPATHLEN-1) { - return NULL; - } - - if (realpath(p, path) == NULL) { - fprintf(stderr,"Failed to find real path for mount point\n"); - exit(1); - } - return strdup(path); -} - -/* Check whether user is allowed to mount on the specified mount point. If it's - OK then we change into that directory - this prevents race conditions */ -static int mount_ok(char *mount_point) -{ - struct stat st; - - if (chdir(mount_point) != 0) { - return -1; - } - - if (stat(".", &st) != 0) { - return -1; - } - - if (!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - return -1; - } - - if ((getuid() != 0) && - ((getuid() != st.st_uid) || - ((st.st_mode & S_IRWXU) != S_IRWXU))) { - errno = EPERM; - return -1; - } - - return 0; -} - -/* Tries to mount using the appropriate format. For 2.2 the struct, - for 2.4 the ascii version. */ -static int -do_mount(char *share_name, uint_t flags, struct smb_mount_data *data) -{ - pstring opts; - struct utsname uts; - char *release, *major, *minor; - char *data1, *data2; - - uname(&uts); - release = uts.release; - major = strtok(release, "."); - minor = strtok(NULL, "."); - if (major && minor && atoi(major) == 2 && atoi(minor) < 4) { - /* < 2.4, assume struct */ - data1 = (char *) data; - data2 = opts; - } else { - /* >= 2.4, assume ascii but fall back on struct */ - data1 = opts; - data2 = (char *) data; - } - - slprintf(opts, sizeof(opts)-1, - "version=7,uid=%d,gid=%d,file_mode=0%o,dir_mode=0%o,%s", - data->uid, data->gid, data->file_mode, data->dir_mode,options); - if (mount(share_name, ".", "smbfs", flags, data1) == 0) - return 0; - return mount(share_name, ".", "smbfs", flags, data2); -} - - int main(int argc, char *argv[]) -{ - char *mount_point, *share_name = NULL; - FILE *mtab; - int fd; - uint_t flags; - struct smb_mount_data data; - struct mntent ment; - - memset(&data, 0, sizeof(struct smb_mount_data)); - - if (argc < 2) { - help(); - exit(1); - } - - if (argv[1][0] == '-') { - help(); - exit(1); - } - - if (getuid() != 0) { - user_mount = 1; - } - - if (geteuid() != 0) { - fprintf(stderr, "smbmnt must be installed suid root for direct user mounts (%d,%d)\n", getuid(), geteuid()); - exit(1); - } - - mount_uid = getuid(); - mount_gid = getgid(); - mount_fmask = umask(0); - umask(mount_fmask); - mount_fmask = ~mount_fmask; - - mount_point = fullpath(argv[1]); - - argv += 1; - argc -= 1; - - if (mount_ok(mount_point) != 0) { - fprintf(stderr, "cannot mount on %s: %s\n", - mount_point, strerror(errno)); - exit(1); - } - - data.version = SMB_MOUNT_VERSION; - - /* getuid() gives us the real uid, who may umount the fs */ - data.mounted_uid = getuid(); - - if (parse_args(argc, argv, &data, &share_name) != 0) { - help(); - return -1; - } - - data.uid = mount_uid; - data.gid = mount_gid; - data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_fmask; - data.dir_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_dmask; - - if (mount_dmask == 0) { - data.dir_mode = data.file_mode; - if ((data.dir_mode & S_IRUSR) != 0) - data.dir_mode |= S_IXUSR; - if ((data.dir_mode & S_IRGRP) != 0) - data.dir_mode |= S_IXGRP; - if ((data.dir_mode & S_IROTH) != 0) - data.dir_mode |= S_IXOTH; - } - - flags = MS_MGC_VAL; - - if (mount_ro) flags |= MS_RDONLY; - - if (do_mount(share_name, flags, &data) < 0) { - switch (errno) { - case ENODEV: - fprintf(stderr, "ERROR: smbfs filesystem not supported by the kernel\n"); - break; - default: - perror("mount error"); - } - fprintf(stderr, "Please refer to the smbmnt(8) manual page\n"); - return -1; - } - - ment.mnt_fsname = share_name ? share_name : "none"; - ment.mnt_dir = mount_point; - ment.mnt_type = "smbfs"; - ment.mnt_opts = ""; - ment.mnt_freq = 0; - ment.mnt_passno= 0; - - mount_point = ment.mnt_dir; - - if (mount_point == NULL) - { - fprintf(stderr, "Mount point too long\n"); - return -1; - } - - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) - { - fprintf(stderr, "Can't get "MOUNTED"~ lock file"); - return 1; - } - close(fd); - - if ((mtab = setmntent(MOUNTED, "a+")) == NULL) - { - fprintf(stderr, "Can't open " MOUNTED); - return 1; - } - - if (addmntent(mtab, &ment) == 1) - { - fprintf(stderr, "Can't write mount entry"); - return 1; - } - if (fchmod(fileno(mtab), 0644) == -1) - { - fprintf(stderr, "Can't set perms on "MOUNTED); - return 1; - } - endmntent(mtab); - - if (unlink(MOUNTED"~") == -1) - { - fprintf(stderr, "Can't remove "MOUNTED"~"); - return 1; - } - - return 0; -} diff --git a/source4/client/smbmount.c b/source4/client/smbmount.c deleted file mode 100644 index c219a42f3a..0000000000 --- a/source4/client/smbmount.c +++ /dev/null @@ -1,942 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMBFS mount program - Copyright (C) Andrew Tridgell 1999 - - 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 3 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, see . -*/ - -#include "includes.h" -#include "system/passwd.h" - -#include -#include -#include - -#define pstrcpy(d,s) safe_strcpy((d),(s),sizeof(pstring)-1) -#define pstrcat(d,s) safe_strcat((d),(s),sizeof(pstring)-1) - -static pstring credentials; -static pstring my_netbios_name; -static pstring password; -static pstring username; -static pstring workgroup; -static pstring mpoint; -static pstring service; -static pstring options; - -static struct in_addr dest_ip; -static bool have_ip; -static int smb_port = 0; -static bool got_user; -static bool got_pass; -static uid_t mount_uid; -static gid_t mount_gid; -static int mount_ro; -static uint_t mount_fmask; -static uint_t mount_dmask; -static bool use_kerberos; -/* TODO: Add code to detect smbfs version in kernel */ -static bool status32_smbfs = false; - -static void usage(void); - -static void exit_parent(int sig) -{ - /* parent simply exits when child says go... */ - exit(0); -} - -static void daemonize(void) -{ - int j, status; - pid_t child_pid; - - signal( SIGTERM, exit_parent ); - - if ((child_pid = sys_fork()) < 0) { - DEBUG(0,("could not fork\n")); - } - - if (child_pid > 0) { - while( 1 ) { - j = waitpid( child_pid, &status, 0 ); - if( j < 0 ) { - if( EINTR == errno ) { - continue; - } - status = errno; - } - break; - } - - /* If we get here - the child exited with some error status */ - if (WIFSIGNALED(status)) - exit(128 + WTERMSIG(status)); - else - exit(WEXITSTATUS(status)); - } - - signal( SIGTERM, SIG_DFL ); - chdir("/"); -} - -static void close_our_files(int client_fd) -{ - int i; - struct rlimit limits; - - getrlimit(RLIMIT_NOFILE,&limits); - for (i = 0; i< limits.rlim_max; i++) { - if (i == client_fd) - continue; - close(i); - } -} - -static void usr1_handler(int x) -{ - return; -} - - -/***************************************************** -return a connection to a server -*******************************************************/ -static struct smbcli_state *do_connection(const char *the_service, bool unicode, int maxprotocol, - struct smbcli_session_options session_options) -{ - struct smbcli_state *c; - struct nmb_name called, calling; - char *server_n; - struct in_addr ip; - pstring server; - char *share; - - if (the_service[0] != '\\' || the_service[1] != '\\') { - usage(); - exit(1); - } - - pstrcpy(server, the_service+2); - share = strchr_m(server,'\\'); - if (!share) { - usage(); - exit(1); - } - *share = 0; - share++; - - server_n = server; - - make_nmb_name(&calling, my_netbios_name, 0x0); - choose_called_name(&called, server, 0x20); - - again: - zero_ip(&ip); - if (have_ip) ip = dest_ip; - - /* have to open a new connection */ - if (!(c=smbcli_initialise(NULL)) || (smbcli_set_port(c, smb_port) != smb_port) || - !smbcli_connect(c, server_n, &ip)) { - DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n)); - if (c) { - talloc_free(c); - } - return NULL; - } - - /* SPNEGO doesn't work till we get NTSTATUS error support */ - /* But it is REQUIRED for kerberos authentication */ - if(!use_kerberos) c->use_spnego = false; - - /* The kernel doesn't yet know how to sign it's packets */ - c->sign_info.allow_smb_signing = false; - - /* Use kerberos authentication if specified */ - c->use_kerberos = use_kerberos; - - if (!smbcli_session_request(c, &calling, &called)) { - char *p; - DEBUG(0,("%d: session request to %s failed (%s)\n", - sys_getpid(), called.name, smbcli_errstr(c))); - talloc_free(c); - if ((p=strchr_m(called.name, '.'))) { - *p = 0; - goto again; - } - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } - return NULL; - } - - DEBUG(4,("%d: session request ok\n", sys_getpid())); - - if (!smbcli_negprot(c, unicode, maxprotocol)) { - DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid())); - talloc_free(c); - return NULL; - } - - if (!got_pass) { - char *pass = getpass("Password: "); - if (pass) { - pstrcpy(password, pass); - } - } - - /* This should be right for current smbfs. Future versions will support - large files as well as unicode and oplocks. */ - if (status32_smbfs) { - c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS | - CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS); - } - else { - c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS | - CAP_NT_FIND | CAP_STATUS32 | - CAP_LEVEL_II_OPLOCKS); - c->force_dos_errors = true; - } - - if (!smbcli_session_setup(c, username, - password, strlen(password), - password, strlen(password), - workgroup, session_options)) { - /* if a password was not supplied then try again with a - null username */ - if (password[0] || !username[0] || - !smbcli_session_setup(c, "", "", 0, "", 0, workgroup, - session_options)) { - DEBUG(0,("%d: session setup failed: %s\n", - sys_getpid(), smbcli_errstr(c))); - talloc_free(c); - return NULL; - } - DEBUG(0,("Anonymous login successful\n")); - } - - DEBUG(4,("%d: session setup ok\n", sys_getpid())); - - if (!smbcli_tconX(c, share, "?????", password, strlen(password)+1)) { - DEBUG(0,("%d: tree connect failed: %s\n", - sys_getpid(), smbcli_errstr(c))); - talloc_free(c); - return NULL; - } - - DEBUG(4,("%d: tconx ok\n", sys_getpid())); - - got_pass = true; - - return c; -} - - -/**************************************************************************** -unmount smbfs (this is a bailout routine to clean up if a reconnect fails) - Code blatently stolen from smbumount.c - -mhw- -****************************************************************************/ -static void smb_umount(const char *mount_point) -{ - int fd; - struct mntent *mnt; - FILE* mtab; - FILE* new_mtab; - - /* Programmers Note: - This routine only gets called to the scene of a disaster - to shoot the survivors... A connection that was working - has now apparently failed. We have an active mount point - (presumably) that we need to dump. If we get errors along - the way - make some noise, but we are already turning out - the lights to exit anyways... - */ - if (umount(mount_point) != 0) { - DEBUG(0,("%d: Could not umount %s: %s\n", - sys_getpid(), mount_point, strerror(errno))); - return; - } - - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) { - DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid())); - return; - } - - close(fd); - - if ((mtab = setmntent(MOUNTED, "r")) == NULL) { - DEBUG(0,("%d: Can't open " MOUNTED ": %s\n", - sys_getpid(), strerror(errno))); - return; - } - -#define MOUNTED_TMP MOUNTED".tmp" - - if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { - DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n", - sys_getpid(), strerror(errno))); - endmntent(mtab); - return; - } - - while ((mnt = getmntent(mtab)) != NULL) { - if (strcmp(mnt->mnt_dir, mount_point) != 0) { - addmntent(new_mtab, mnt); - } - } - - endmntent(mtab); - - if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { - DEBUG(0,("%d: Error changing mode of %s: %s\n", - sys_getpid(), MOUNTED_TMP, strerror(errno))); - return; - } - - endmntent(new_mtab); - - if (rename(MOUNTED_TMP, MOUNTED) < 0) { - DEBUG(0,("%d: Cannot rename %s to %s: %s\n", - sys_getpid(), MOUNTED, MOUNTED_TMP, strerror(errno))); - return; - } - - if (unlink(MOUNTED"~") == -1) { - DEBUG(0,("%d: Can't remove "MOUNTED"~", sys_getpid())); - return; - } -} - - -/* - * Call the smbfs ioctl to install a connection socket, - * then wait for a signal to reconnect. Note that we do - * not exit after open_sockets() or send_login() errors, - * as the smbfs mount would then have no way to recover. - */ -static void send_fs_socket(struct loadparm_context *lp_ctx, - const char *the_service, const char *mount_point, struct smbcli_state *c) -{ - int fd, closed = 0, res = 1; - pid_t parentpid = getppid(); - struct smb_conn_opt conn_options; - struct smbcli_session_options session_options; - - lp_smbcli_session_options(lp_ctx, &session_options); - - memset(&conn_options, 0, sizeof(conn_options)); - - while (1) { - if ((fd = open(mount_point, O_RDONLY)) < 0) { - DEBUG(0,("mount.smbfs[%d]: can't open %s\n", - sys_getpid(), mount_point)); - break; - } - - conn_options.fd = c->fd; - conn_options.protocol = c->protocol; - conn_options.case_handling = SMB_CASE_DEFAULT; - conn_options.max_xmit = c->max_xmit; - conn_options.server_uid = c->vuid; - conn_options.tid = c->cnum; - conn_options.secmode = c->sec_mode; - conn_options.rawmode = 0; - conn_options.sesskey = c->sesskey; - conn_options.maxraw = 0; - conn_options.capabilities = c->capabilities; - conn_options.serverzone = c->serverzone/60; - - res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options); - if (res != 0) { - DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n", - sys_getpid(), res)); - close(fd); - break; - } - - if (parentpid) { - /* Ok... We are going to kill the parent. Now - is the time to break the process group... */ - setsid(); - /* Send a signal to the parent to terminate */ - kill(parentpid, SIGTERM); - parentpid = 0; - } - - close(fd); - - /* This looks wierd but we are only closing the userspace - side, the connection has already been passed to smbfs and - it has increased the usage count on the socket. - - If we don't do this we will "leak" sockets and memory on - each reconnection we have to make. */ - talloc_free(c); - c = NULL; - - if (!closed) { - /* redirect stdout & stderr since we can't know that - the library functions we use are using DEBUG. */ - if ( (fd = open("/dev/null", O_WRONLY)) < 0) - DEBUG(2,("mount.smbfs: can't open /dev/null\n")); - close_our_files(fd); - if (fd >= 0) { - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - close(fd); - } - - /* here we are no longer interactive */ - set_remote_machine_name("smbmount"); /* sneaky ... */ - setup_logging("mount.smbfs", DEBUG_STDERR); - reopen_logs(); - DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid())); - - closed = 1; - } - - /* Wait for a signal from smbfs ... but don't continue - until we actually get a new connection. */ - while (!c) { - CatchSignal(SIGUSR1, &usr1_handler); - pause(); - DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid())); - c = do_connection(the_service, - lp_unicode(lp_ctx), - lp_cli_maxprotocol(lp_ctx), - session_options); - } - } - - smb_umount(mount_point); - DEBUG(2,("mount.smbfs[%d]: exit\n", sys_getpid())); - exit(1); -} - - -/** - * Mount a smbfs - **/ -static void init_mount(struct loadparm_context *lp_ctx) -{ - char mount_point[MAXPATHLEN+1]; - pstring tmp; - pstring svc2; - struct smbcli_state *c; - char *args[20]; - int i, status; - struct smbcli_session_options session_options; - - if (realpath(mpoint, mount_point) == NULL) { - fprintf(stderr, "Could not resolve mount point %s\n", mpoint); - return; - } - - lp_smbcli_session_options(lp_ctx, &session_options); - - c = do_connection(service, lp_unicode(lp_ctx), lp_cli_maxprotocol(lp_ctx), - session_options); - if (!c) { - fprintf(stderr,"SMB connection failed\n"); - exit(1); - } - - /* - Set up to return as a daemon child and wait in the parent - until the child say it's ready... - */ - daemonize(); - - pstrcpy(svc2, service); - string_replace(svc2, '\\','/'); - string_replace(svc2, ' ','_'); - - memset(args, 0, sizeof(args[0])*20); - - i=0; - args[i++] = "smbmnt"; - - args[i++] = mount_point; - args[i++] = "-s"; - args[i++] = svc2; - - if (mount_ro) { - args[i++] = "-r"; - } - if (mount_uid) { - slprintf(tmp, sizeof(tmp)-1, "%d", mount_uid); - args[i++] = "-u"; - args[i++] = smb_xstrdup(tmp); - } - if (mount_gid) { - slprintf(tmp, sizeof(tmp)-1, "%d", mount_gid); - args[i++] = "-g"; - args[i++] = smb_xstrdup(tmp); - } - if (mount_fmask) { - slprintf(tmp, sizeof(tmp)-1, "0%o", mount_fmask); - args[i++] = "-f"; - args[i++] = smb_xstrdup(tmp); - } - if (mount_dmask) { - slprintf(tmp, sizeof(tmp)-1, "0%o", mount_dmask); - args[i++] = "-d"; - args[i++] = smb_xstrdup(tmp); - } - if (options) { - args[i++] = "-o"; - args[i++] = options; - } - - if (sys_fork() == 0) { - char *smbmnt_path; - - asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR); - - if (file_exist(smbmnt_path)) { - execv(smbmnt_path, args); - fprintf(stderr, - "smbfs/init_mount: execv of %s failed. Error was %s.", - smbmnt_path, strerror(errno)); - } else { - execvp("smbmnt", args); - fprintf(stderr, - "smbfs/init_mount: execv of %s failed. Error was %s.", - "smbmnt", strerror(errno)); - } - free(smbmnt_path); - exit(1); - } - - if (waitpid(-1, &status, 0) == -1) { - fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) ); - /* FIXME: do some proper error handling */ - exit(1); - } - - if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { - fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status)); - /* FIXME: do some proper error handling */ - exit(1); - } else if (WIFSIGNALED(status)) { - fprintf(stderr, "smbmnt killed by signal %d\n", WTERMSIG(status)); - exit(1); - } - - /* Ok... This is the rubicon for that mount point... At any point - after this, if the connections fail and can not be reconstructed - for any reason, we will have to unmount the mount point. There - is no exit from the next call... - */ - send_fs_socket(lp_ctx, service, mount_point, c); -} - - -/**************************************************************************** -get a password from a a file or file descriptor -exit on failure (from smbclient, move to libsmb or shared .c file?) -****************************************************************************/ -static void get_password_file(void) -{ - int fd = -1; - char *p; - bool close_it = false; - pstring spec; - char pass[128]; - - if ((p = getenv("PASSWD_FD")) != NULL) { - pstrcpy(spec, "descriptor "); - pstrcat(spec, p); - sscanf(p, "%d", &fd); - close_it = false; - } else if ((p = getenv("PASSWD_FILE")) != NULL) { - fd = open(p, O_RDONLY, 0); - pstrcpy(spec, p); - if (fd < 0) { - fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n", - spec, strerror(errno)); - exit(1); - } - close_it = true; - } - - for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */ - p && p - pass < sizeof(pass);) { - switch (read(fd, p, 1)) { - case 1: - if (*p != '\n' && *p != '\0') { - *++p = '\0'; /* advance p, and null-terminate pass */ - break; - } - case 0: - if (p - pass) { - *p = '\0'; /* null-terminate it, just in case... */ - p = NULL; /* then force the loop condition to become false */ - break; - } else { - fprintf(stderr, "Error reading password from file %s: %s\n", - spec, "empty password\n"); - exit(1); - } - - default: - fprintf(stderr, "Error reading password from file %s: %s\n", - spec, strerror(errno)); - exit(1); - } - } - pstrcpy(password, pass); - if (close_it) - close(fd); -} - -/**************************************************************************** -get username and password from a credentials file -exit on failure (from smbclient, move to libsmb or shared .c file?) -****************************************************************************/ -static void read_credentials_file(char *filename) -{ - FILE *auth; - fstring buf; - uint16_t len = 0; - char *ptr, *val, *param; - - if ((auth=sys_fopen(filename, "r")) == NULL) - { - /* fail if we can't open the credentials file */ - DEBUG(0,("ERROR: Unable to open credentials file!\n")); - exit (-1); - } - - while (!feof(auth)) - { - /* get a line from the file */ - if (!fgets (buf, sizeof(buf), auth)) - continue; - len = strlen(buf); - - if ((len) && (buf[len-1]=='\n')) - { - buf[len-1] = '\0'; - len--; - } - if (len == 0) - continue; - - /* break up the line into parameter & value. - will need to eat a little whitespace possibly */ - param = buf; - if (!(ptr = strchr (buf, '='))) - continue; - val = ptr+1; - *ptr = '\0'; - - /* eat leading white space */ - while ((*val!='\0') && ((*val==' ') || (*val=='\t'))) - val++; - - if (strwicmp("password", param) == 0) - { - pstrcpy(password, val); - got_pass = true; - } - else if (strwicmp("username", param) == 0) { - pstrcpy(username, val); - } - - memset(buf, 0, sizeof(buf)); - } - fclose(auth); -} - - -/**************************************************************************** -usage on the program -****************************************************************************/ -static void usage(void) -{ - printf("Usage: mount.smbfs service mountpoint [-o options,...]\n"); - - printf("Version %s\n\n",VERSION); - - printf( -"Options:\n\ - username= SMB username\n\ - password= SMB password\n\ - credentials= file with username/password\n\ - krb use kerberos (active directory)\n\ - netbiosname= source NetBIOS name\n\ - uid= mount uid or username\n\ - gid= mount gid or groupname\n\ - port= remote SMB port number\n\ - fmask= file umask\n\ - dmask= directory umask\n\ - debug= debug level\n\ - ip= destination host or IP address\n\ - workgroup= workgroup on destination\n\ - sockopt= TCP socket options\n\ - scope= NetBIOS scope\n\ - iocharset= Linux charset (iso8859-1, utf8)\n\ - codepage= server codepage (cp850)\n\ - ttl= dircache time to live\n\ - guest don't prompt for a password\n\ - ro mount read-only\n\ - rw mount read-write\n\ -\n\ -This command is designed to be run from within /bin/mount by giving\n\ -the option '-t smbfs'. For example:\n\ - mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test\n\ -"); -} - - -/**************************************************************************** - Argument parsing for mount.smbfs interface - mount will call us like this: - mount.smbfs device mountpoint -o - - is never empty, containing at least rw or ro - ****************************************************************************/ -static void parse_mount_smb(int argc, char **argv) -{ - int opt; - char *opts; - char *opteq; - extern char *optarg; - int val; - char *p; - - /* FIXME: This function can silently fail if the arguments are - * not in the expected order. - - > The arguments syntax of smbmount 2.2.3a (smbfs of Debian stable) - > requires that one gives "-o" before further options like username=... - > . Without -o, the username=.. setting is *silently* ignored. I've - > spent about an hour trying to find out why I couldn't log in now.. - - */ - - - if (argc < 2 || argv[1][0] == '-') { - usage(); - exit(1); - } - - pstrcpy(service, argv[1]); - pstrcpy(mpoint, argv[2]); - - /* Convert any '/' characters in the service name to - '\' characters */ - string_replace(service, '/','\\'); - argc -= 2; - argv += 2; - - opt = getopt(argc, argv, "o:"); - if(opt != 'o') { - return; - } - - options[0] = 0; - p = options; - - /* - * option parsing from nfsmount.c (util-linux-2.9u) - */ - for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) { - DEBUG(3, ("opts: %s\n", opts)); - if ((opteq = strchr_m(opts, '='))) { - val = atoi(opteq + 1); - *opteq = '\0'; - - if (!strcmp(opts, "username") || - !strcmp(opts, "logon")) { - char *lp; - got_user = true; - pstrcpy(username,opteq+1); - if ((lp=strchr_m(username,'%'))) { - *lp = 0; - pstrcpy(password,lp+1); - got_pass = true; - memset(strchr_m(opteq+1,'%')+1,'X',strlen(password)); - } - if ((lp=strchr_m(username,'/'))) { - *lp = 0; - pstrcpy(workgroup,lp+1); - } - } else if(!strcmp(opts, "passwd") || - !strcmp(opts, "password")) { - pstrcpy(password,opteq+1); - got_pass = true; - memset(opteq+1,'X',strlen(password)); - } else if(!strcmp(opts, "credentials")) { - pstrcpy(credentials,opteq+1); - } else if(!strcmp(opts, "netbiosname")) { - pstrcpy(my_netbios_name,opteq+1); - } else if(!strcmp(opts, "uid")) { - mount_uid = nametouid(opteq+1); - } else if(!strcmp(opts, "gid")) { - mount_gid = nametogid(opteq+1); - } else if(!strcmp(opts, "port")) { - smb_port = val; - } else if(!strcmp(opts, "fmask")) { - mount_fmask = strtol(opteq+1, NULL, 8); - } else if(!strcmp(opts, "dmask")) { - mount_dmask = strtol(opteq+1, NULL, 8); - } else if(!strcmp(opts, "debug")) { - DEBUGLEVEL = val; - } else if(!strcmp(opts, "ip")) { - dest_ip = interpret_addr2(opteq+1); - if (is_zero_ip_v4(dest_ip)) { - fprintf(stderr,"Can't resolve address %s\n", opteq+1); - exit(1); - } - have_ip = true; - } else if(!strcmp(opts, "workgroup")) { - pstrcpy(workgroup,opteq+1); - } else if(!strcmp(opts, "sockopt")) { - lp_set_cmdline("socket options", opteq+1); - } else if(!strcmp(opts, "scope")) { - lp_set_cmdline("netbios scope", opteq+1); - } else { - slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1); - p += strlen(p); - } - } else { - val = 1; - if(!strcmp(opts, "nocaps")) { - fprintf(stderr, "Unhandled option: %s\n", opteq+1); - exit(1); - } else if(!strcmp(opts, "guest")) { - *password = '\0'; - got_pass = true; - } else if(!strcmp(opts, "krb")) { -#ifdef HAVE_KRB5 - - use_kerberos = true; - if(!status32_smbfs) - fprintf(stderr, "Warning: kerberos support will only work for samba servers\n"); -#else - fprintf(stderr,"No kerberos support compiled in\n"); - exit(1); -#endif - } else if(!strcmp(opts, "rw")) { - mount_ro = 0; - } else if(!strcmp(opts, "ro")) { - mount_ro = 1; - } else { - strncpy(p, opts, sizeof(pstring) - (p - options) - 1); - p += strlen(opts); - *p++ = ','; - *p = 0; - } - } - } - - if (!*service) { - usage(); - exit(1); - } - - if (p != options) { - *(p-1) = 0; /* remove trailing , */ - DEBUG(3,("passthrough options '%s'\n", options)); - } -} - -/**************************************************************************** - main program -****************************************************************************/ - int main(int argc,char *argv[]) -{ - extern char *optarg; - extern int optind; - char *p; - struct loadparm_context *lp_ctx; - - DEBUGLEVEL = 1; - - /* here we are interactive, even if run from autofs */ - setup_logging("mount.smbfs",DEBUG_STDERR); - -#if 0 /* JRA - Urban says not needed ? */ - /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default - is to not announce any unicode capabilities as current smbfs does - not support it. */ - p = getenv("CLI_FORCE_ASCII"); - if (p && !strcmp(p, "false")) - unsetenv("CLI_FORCE_ASCII"); - else - setenv("CLI_FORCE_ASCII", "true", 1); -#endif - - if (getenv("USER")) { - pstrcpy(username,getenv("USER")); - - if ((p=strchr_m(username,'%'))) { - *p = 0; - pstrcpy(password,p+1); - got_pass = true; - memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password)); - } - strupper(username); - } - - if (getenv("PASSWD")) { - pstrcpy(password, getenv("PASSWD")); - got_pass = true; - } - - if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) { - get_password_file(); - got_pass = true; - } - - if (*username == 0 && getenv("LOGNAME")) { - pstrcpy(username,getenv("LOGNAME")); - } - - lp_ctx = loadparm_init(talloc_autofree_context()); - - if (!lp_load(lp_ctx, dyn_CONFIGFILE)) { - fprintf(stderr, "Can't load %s - run testparm to debug it\n", - lp_config_file()); - } - - parse_mount_smb(argc, argv); - - if (use_kerberos && !got_user) { - got_pass = true; - } - - if (*credentials != 0) { - read_credentials_file(credentials); - } - - DEBUG(3,("mount.smbfs started (version %s)\n", VERSION)); - - if (*workgroup == 0) { - pstrcpy(workgroup, lp_workgroup()); - } - - if (!*my_netbios_name) { - pstrcpy(my_netbios_name, myhostname()); - } - strupper(my_netbios_name); - - init_mount(lp_ctx); - return 0; -} diff --git a/source4/client/smbumount.c b/source4/client/smbumount.c deleted file mode 100644 index 9ea3083a6f..0000000000 --- a/source4/client/smbumount.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * smbumount.c - * - * Copyright (C) 1995-1998 by Volker Lendecke - * - */ - -#include "includes.h" - -#include - -#include -#include -#include -#include -#include - -/* This is a (hopefully) temporary hack due to the fact that - sizeof( uid_t ) != sizeof( __kernel_uid_t ) under glibc. - This may change in the future and smb.h may get fixed in the - future. In the mean time, it's ugly hack time - get over it. -*/ -#undef SMB_IOC_GETMOUNTUID -#define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t) - -#ifndef O_NOFOLLOW -#define O_NOFOLLOW 0400000 -#endif - -static void -usage(void) -{ - printf("usage: smbumount mountpoint\n"); -} - -static int -umount_ok(const char *mount_point) -{ - /* we set O_NOFOLLOW to prevent users playing games with symlinks to - umount filesystems they don't own */ - int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0); - __kernel_uid_t mount_uid; - - if (fid == -1) { - fprintf(stderr, "Could not open %s: %s\n", - mount_point, strerror(errno)); - return -1; - } - - if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid) != 0) { - fprintf(stderr, "%s probably not smb-filesystem\n", - mount_point); - return -1; - } - - if ((getuid() != 0) - && (mount_uid != getuid())) { - fprintf(stderr, "You are not allowed to umount %s\n", - mount_point); - return -1; - } - - close(fid); - return 0; -} - -/* Make a canonical pathname from PATH. Returns a freshly malloced string. - It is up the *caller* to ensure that the PATH is sensible. i.e. - canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.'' - is not a legal pathname for ``/dev/fd0'' Anything we cannot parse - we return unmodified. */ -static char * -canonicalize (char *path) -{ - char *canonical = malloc (PATH_MAX + 1); - - if (!canonical) { - fprintf(stderr, "Error! Not enough memory!\n"); - return NULL; - } - - if (strlen(path) > PATH_MAX) { - fprintf(stderr, "Mount point string too long\n"); - return NULL; - } - - if (path == NULL) - return NULL; - - if (realpath (path, canonical)) - return canonical; - - strncpy (canonical, path, PATH_MAX); - canonical[PATH_MAX] = '\0'; - return canonical; -} - - -int -main(int argc, char *argv[]) -{ - int fd; - char* mount_point; - struct mntent *mnt; - FILE* mtab; - FILE* new_mtab; - - if (argc != 2) { - usage(); - exit(1); - } - - if (geteuid() != 0) { - fprintf(stderr, "smbumount must be installed suid root\n"); - exit(1); - } - - mount_point = canonicalize(argv[1]); - - if (mount_point == NULL) - { - exit(1); - } - - if (umount_ok(mount_point) != 0) { - exit(1); - } - - if (umount(mount_point) != 0) { - fprintf(stderr, "Could not umount %s: %s\n", - mount_point, strerror(errno)); - exit(1); - } - - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) - { - fprintf(stderr, "Can't get "MOUNTED"~ lock file"); - return 1; - } - close(fd); - - if ((mtab = setmntent(MOUNTED, "r")) == NULL) { - fprintf(stderr, "Can't open " MOUNTED ": %s\n", - strerror(errno)); - return 1; - } - -#define MOUNTED_TMP MOUNTED".tmp" - - if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { - fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n", - strerror(errno)); - endmntent(mtab); - return 1; - } - - while ((mnt = getmntent(mtab)) != NULL) { - if (strcmp(mnt->mnt_dir, mount_point) != 0) { - addmntent(new_mtab, mnt); - } - } - - endmntent(mtab); - - if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { - fprintf(stderr, "Error changing mode of %s: %s\n", - MOUNTED_TMP, strerror(errno)); - exit(1); - } - - endmntent(new_mtab); - - if (rename(MOUNTED_TMP, MOUNTED) < 0) { - fprintf(stderr, "Cannot rename %s to %s: %s\n", - MOUNTED, MOUNTED_TMP, strerror(errno)); - exit(1); - } - - if (unlink(MOUNTED"~") == -1) - { - fprintf(stderr, "Can't remove "MOUNTED"~"); - return 1; - } - - return 0; -} -- cgit From 10f076a77de87c036a083533cb34d65eb5f7044a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 May 2009 14:13:11 +1000 Subject: Explicitly list RPC-SAMR-PASSWORDS-PWDLASTSET and RPC-SAMR-USERS-PRIVILAGES as slow --- source4/selftest/tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/selftest/tests.sh b/source4/selftest/tests.sh index 79199bc2c0..58cdc0898b 100755 --- a/source4/selftest/tests.sh +++ b/source4/selftest/tests.sh @@ -117,7 +117,7 @@ plantest "ldb" none TEST_DATA_PREFIX=\$PREFIX $LDBDIR/tests/test-tdb.sh ncacn_np_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-HANDLES RPC-SAMSYNC RPC-SAMBA3SESSIONKEY RPC-SAMBA3-GETUSERNAME RPC-SAMBA3-LSA RPC-BINDSAMBA3 RPC-NETLOGSAMBA3 RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT" ncalrpc_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-DRSUAPI RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT" ncacn_ip_tcp_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-HANDLES RPC-DSSYNC RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT RPC-OBJECTUUID" -slow_ncacn_np_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-PASSWORDS" +slow_ncacn_np_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-USERS-PRIVILEGES RPC-SAMR-PASSWORDS RPC-SAMR-PASSWORDS-PWDLASTSET" slow_ncalrpc_tests="RPC-SAMR RPC-SAMR-PASSWORDS" slow_ncacn_ip_tcp_tests="RPC-SAMR RPC-SAMR-PASSWORDS RPC-CRACKNAMES" -- cgit From 98ff29291b26abe35efc6cc2552b9e49c4330983 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 May 2009 14:49:29 +1000 Subject: s4:torture Half the repeditive tests run by RPC-SAMR-PASSWORDS-PWDLASTSET --- source4/torture/rpc/samr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index d13c547a2b..1f7bb67eca 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -2867,7 +2867,7 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p, int delay = 50000; bool set_levels[] = { false, true }; bool query_levels[] = { false, true }; - uint32_t levels[] = { 18, 21, 23, 24, 25, 26 }; + uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */ uint32_t nonzeros[] = { 1, 24 }; uint32_t fields_present[] = { 0, @@ -2918,10 +2918,15 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p, (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2) combinations */ #if 0 +#define TEST_ALL_LEVELS 1 #define TEST_SET_LEVELS 1 #define TEST_QUERY_LEVELS 1 #endif +#ifdef TEST_ALL_LEVELS for (l=0; l Date: Fri, 29 May 2009 08:35:41 +1000 Subject: s4:torture Clean up users and groups added in RPC-SAMR-LARGE-DC --- source4/torture/rpc/samr.c | 48 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 1f7bb67eca..c5050edc52 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -6176,6 +6176,8 @@ static bool test_ManyObjects(struct dcerpc_pipe *p, NTSTATUS status; uint32_t i; + struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total); + /* query */ { @@ -6208,29 +6210,25 @@ static bool test_ManyObjects(struct dcerpc_pipe *p, for (i=0; i < num_total; i++) { - struct policy_handle handle; const char *name = NULL; - ZERO_STRUCT(handle); - switch (which_ops) { case TORTURE_SAMR_MANY_ACCOUNTS: name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i); - ret &= test_CreateUser(p, tctx, domain_handle, name, &handle, domain_sid, 0, NULL, false); + ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false); break; case TORTURE_SAMR_MANY_GROUPS: name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i); - ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handle, domain_sid, false); + ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false); break; case TORTURE_SAMR_MANY_ALIASES: name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i); - ret &= test_CreateAlias(p, tctx, domain_handle, name, &handle, domain_sid, false); + ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false); break; default: return false; } - if (!policy_handle_empty(&handle)) { - ret &= test_samr_handle_Close(p, tctx, &handle); + if (!policy_handle_empty(&handles[i])) { num_created++; } } @@ -6251,9 +6249,6 @@ static bool test_ManyObjects(struct dcerpc_pipe *p, return false; } - torture_assert_int_equal(tctx, num_enum, num_anounced + num_created, - "unexpected number of results returned in enum call"); -#if 0 /* TODO: dispinfo */ switch (which_ops) { @@ -6267,9 +6262,40 @@ static bool test_ManyObjects(struct dcerpc_pipe *p, return false; } + + /* delete */ + + for (i=0; i < num_total; i++) { + + if (policy_handle_empty(&handles[i])) { + continue; + } + + switch (which_ops) { + case TORTURE_SAMR_MANY_ACCOUNTS: + ret &= test_DeleteUser(p, tctx, &handles[i]); + break; + case TORTURE_SAMR_MANY_GROUPS: + ret &= test_DeleteDomainGroup(p, tctx, &handles[i]); + break; + case TORTURE_SAMR_MANY_ALIASES: + ret &= test_DeleteAlias(p, tctx, &handles[i]); + break; + default: + return false; + } + + ret &= test_samr_handle_Close(p, tctx, &handles[i]); + } + + talloc_free(handles); + +#if 0 torture_assert_int_equal(tctx, num_disp, num_anounced + num_created, "unexpected number of results returned in dispinfo call"); #endif + torture_assert_int_equal(tctx, num_enum, num_anounced + num_created, + "unexpected number of results returned in enum call"); return ret; } -- cgit From a2e72ac5562d69fa40c7389a9d9d7e6551e39b41 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 May 2009 08:35:59 +1000 Subject: s4:torture Don't run QueryDisplayInfo test for SAMR-USERS-PRIVILEGES --- source4/torture/rpc/samr.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index c5050edc52..d9e4205e93 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -6335,9 +6335,14 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, ret &= test_samr_handle_Close(p, tctx, handle); switch (which_ops) { - case TORTURE_SAMR_USER_ATTRIBUTES: - case TORTURE_SAMR_USER_PRIVILEGES: case TORTURE_SAMR_PASSWORDS: + case TORTURE_SAMR_USER_PRIVILEGES: + if (!torture_setting_bool(tctx, "samba3", false)) { + ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL); + } + ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true); + break; + case TORTURE_SAMR_USER_ATTRIBUTES: if (!torture_setting_bool(tctx, "samba3", false)) { ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL); } -- cgit From d409a12ccd20abd45f8c0f399e55094f5ff9d0a7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 May 2009 12:15:28 +1000 Subject: s4:setup Remove generated attributes from provision_configuration Incorrectly added in 95eeef91d3ed7daf8e19029eadcc610caf26db63, and found by OpenLDAP backend tests run by Theodor Chirana Andrew Bartlett --- source4/setup/provision_configuration.ldif | 195 ----------------------------- 1 file changed, 195 deletions(-) diff --git a/source4/setup/provision_configuration.ldif b/source4/setup/provision_configuration.ldif index 63b807ba4a..fff380505f 100644 --- a/source4/setup/provision_configuration.ldif +++ b/source4/setup/provision_configuration.ldif @@ -96,21 +96,15 @@ dn: CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: container cn: Extended-Rights -instanceType: 4 -showInAdvancedViewOnly: TRUE systemFlags: -2147483648 -objectCategory: CN=Container,CN=Schema,${CONFIGDN} dn: CN=Change-Rid-Master,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Change-Rid-Master -instanceType: 4 displayName: Change Rid Master -showInAdvancedViewOnly: TRUE rightsGuid: d58d5f36-0a98-11d1-adbb-00c04fd8d5cd appliesTo: 6617188d-8f3c-11d0-afda-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 29 validAccesses: 256 @@ -118,12 +112,9 @@ dn: CN=Do-Garbage-Collection,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Do-Garbage-Collection -instanceType: 4 displayName: Do Garbage Collection -showInAdvancedViewOnly: TRUE rightsGuid: fec364e0-0a98-11d1-adbb-00c04fd8d5cd appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 31 validAccesses: 256 @@ -131,12 +122,9 @@ dn: CN=Recalculate-Hierarchy,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Recalculate-Hierarchy -instanceType: 4 displayName: Recalculate Hierarchy -showInAdvancedViewOnly: TRUE rightsGuid: 0bc1554e-0a99-11d1-adbb-00c04fd8d5cd appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 32 validAccesses: 256 @@ -144,12 +132,9 @@ dn: CN=Allocate-Rids,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Allocate-Rids -instanceType: 4 displayName: Allocate Rids -showInAdvancedViewOnly: TRUE rightsGuid: 1abd7cf8-0a99-11d1-adbb-00c04fd8d5cd appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 33 validAccesses: 256 @@ -157,12 +142,9 @@ dn: CN=Change-PDC,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Change-PDC -instanceType: 4 displayName: Change PDC -showInAdvancedViewOnly: TRUE rightsGuid: bae50096-4752-11d1-9052-00c04fc2d4cf appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 34 validAccesses: 256 @@ -170,12 +152,9 @@ dn: CN=Add-GUID,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Add-GUID -instanceType: 4 displayName: Add GUID -showInAdvancedViewOnly: TRUE rightsGuid: 440820ad-65b4-11d1-a3da-0000f875ae0d appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 35 validAccesses: 256 @@ -183,12 +162,9 @@ dn: CN=Change-Domain-Master,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Change-Domain-Master -instanceType: 4 displayName: Change Domain Master -showInAdvancedViewOnly: TRUE rightsGuid: 014bf69c-7b3b-11d1-85f6-08002be74fab appliesTo: ef9e60e0-56f7-11d1-a9c6-0000f80367c1 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 36 validAccesses: 256 @@ -196,14 +172,11 @@ dn: CN=Public-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Public-Information -instanceType: 4 displayName: Public Information -showInAdvancedViewOnly: TRUE rightsGuid: e48d0154-bcf8-11d1-8702-00c04fb96050 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 37 validAccesses: 48 @@ -211,12 +184,9 @@ dn: CN=msmq-Receive-Dead-Letter,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Receive-Dead-Letter -instanceType: 4 displayName: Receive Dead Letter -showInAdvancedViewOnly: TRUE rightsGuid: 4b6e08c0-df3c-11d1-9c86-006008764d0e appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 38 validAccesses: 256 @@ -224,12 +194,9 @@ dn: CN=msmq-Peek-Dead-Letter,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Peek-Dead-Letter -instanceType: 4 displayName: Peek Dead Letter -showInAdvancedViewOnly: TRUE rightsGuid: 4b6e08c1-df3c-11d1-9c86-006008764d0e appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 39 validAccesses: 256 @@ -237,12 +204,9 @@ dn: CN=msmq-Receive-computer-Journal,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Receive-computer-Journal -instanceType: 4 displayName: Receive Computer Journal -showInAdvancedViewOnly: TRUE rightsGuid: 4b6e08c2-df3c-11d1-9c86-006008764d0e appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 40 validAccesses: 256 @@ -250,12 +214,9 @@ dn: CN=msmq-Peek-computer-Journal,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Peek-computer-Journal -instanceType: 4 displayName: Peek Computer Journal -showInAdvancedViewOnly: TRUE rightsGuid: 4b6e08c3-df3c-11d1-9c86-006008764d0e appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 41 validAccesses: 256 @@ -263,12 +224,9 @@ dn: CN=msmq-Receive,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Receive -instanceType: 4 displayName: Receive Message -showInAdvancedViewOnly: TRUE rightsGuid: 06bd3200-df3e-11d1-9c86-006008764d0e appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 42 validAccesses: 256 @@ -276,12 +234,9 @@ dn: CN=msmq-Peek,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Peek -instanceType: 4 displayName: Peek Message -showInAdvancedViewOnly: TRUE rightsGuid: 06bd3201-df3e-11d1-9c86-006008764d0e appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 43 validAccesses: 256 @@ -289,13 +244,10 @@ dn: CN=msmq-Send,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Send -instanceType: 4 displayName: Send Message -showInAdvancedViewOnly: TRUE rightsGuid: 06bd3202-df3e-11d1-9c86-006008764d0e appliesTo: 46b27aac-aafa-4ffb-b773-e5bf621ee87b appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 44 validAccesses: 256 @@ -303,12 +255,9 @@ dn: CN=msmq-Receive-journal,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Receive-journal -instanceType: 4 displayName: Receive Journal -showInAdvancedViewOnly: TRUE rightsGuid: 06bd3203-df3e-11d1-9c86-006008764d0e appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 45 validAccesses: 256 @@ -316,12 +265,9 @@ dn: CN=msmq-Open-Connector,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Open-Connector -instanceType: 4 displayName: Open Connector Queue -showInAdvancedViewOnly: TRUE rightsGuid: b4e60130-df3f-11d1-9c86-006008764d0e appliesTo: bf967ab3-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 46 validAccesses: 256 @@ -329,12 +275,9 @@ dn: CN=Apply-Group-Policy,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Apply-Group-Policy -instanceType: 4 displayName: Apply Group Policy -showInAdvancedViewOnly: TRUE rightsGuid: edacfd8f-ffb3-11d1-b41d-00a0c968f939 appliesTo: f30e3bc2-9ff0-11d1-b603-0000f80367c1 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 47 validAccesses: 256 @@ -342,13 +285,10 @@ dn: CN=RAS-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: RAS-Information -instanceType: 4 displayName: Remote Access Information -showInAdvancedViewOnly: TRUE rightsGuid: 037088f8-0ae1-11d2-b422-00a0c968f939 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 48 validAccesses: 48 @@ -356,12 +296,9 @@ dn: CN=DS-Install-Replica,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Install-Replica -instanceType: 4 displayName: Add/Remove Replica In Domain -showInAdvancedViewOnly: TRUE rightsGuid: 9923a32a-3607-11d2-b9be-0000f87a36b2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 49 validAccesses: 256 @@ -369,12 +306,9 @@ dn: CN=Change-Infrastructure-Master,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Change-Infrastructure-Master -instanceType: 4 displayName: Change Infrastructure Master -showInAdvancedViewOnly: TRUE rightsGuid: cc17b1fb-33d9-11d2-97d4-00c04fd8d5cd appliesTo: 2df90d89-009f-11d2-aa4c-00c04fd7d83a -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 50 validAccesses: 256 @@ -382,12 +316,9 @@ dn: CN=Update-Schema-Cache,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Update-Schema-Cache -instanceType: 4 displayName: Update Schema Cache -showInAdvancedViewOnly: TRUE rightsGuid: be2bb760-7f46-11d2-b9ad-00c04f79f805 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 51 validAccesses: 256 @@ -395,12 +326,9 @@ dn: CN=Recalculate-Security-Inheritance,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Recalculate-Security-Inheritance -instanceType: 4 displayName: Recalculate Security Inheritance -showInAdvancedViewOnly: TRUE rightsGuid: 62dd28a8-7f46-11d2-b9ad-00c04f79f805 appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 52 validAccesses: 256 @@ -408,12 +336,9 @@ dn: CN=DS-Check-Stale-Phantoms,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Check-Stale-Phantoms -instanceType: 4 displayName: Check Stale Phantoms -showInAdvancedViewOnly: TRUE rightsGuid: 69ae6200-7f46-11d2-b9ad-00c04f79f805 appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 53 validAccesses: 256 @@ -421,12 +346,9 @@ dn: CN=Certificate-Enrollment,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Certificate-Enrollment -instanceType: 4 displayName: Enroll -showInAdvancedViewOnly: TRUE rightsGuid: 0e10c968-78fb-11d2-90d4-00c04f79dc55 appliesTo: e5209ca2-3bba-11d2-90cc-00c04fd91ab1 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 54 validAccesses: 256 @@ -434,12 +356,9 @@ dn: CN=Self-Membership,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Self-Membership -instanceType: 4 displayName: Add/Remove self as member -showInAdvancedViewOnly: TRUE rightsGuid: bf9679c0-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a9c-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 12 validAccesses: 8 @@ -447,12 +366,9 @@ dn: CN=Validated-DNS-Host-Name,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Validated-DNS-Host-Name -instanceType: 4 displayName: Validated write to DNS host name -showInAdvancedViewOnly: TRUE rightsGuid: 72e39547-7b18-11d1-adef-00c04fd8d5cd appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 13 validAccesses: 8 @@ -460,12 +376,9 @@ dn: CN=Validated-SPN,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Validated-SPN -instanceType: 4 displayName: Validated write to service principal name -showInAdvancedViewOnly: TRUE rightsGuid: f3a64788-5306-11d1-a9c5-0000f80367c1 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 14 validAccesses: 8 @@ -473,13 +386,10 @@ dn: CN=Generate-RSoP-Planning,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Generate-RSoP-Planning -instanceType: 4 displayName: Generate Resultant Set of Policy (Planning) -showInAdvancedViewOnly: TRUE rightsGuid: b7b1b3dd-ab09-4242-9e30-9980e5d322f7 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 appliesTo: bf967aa5-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 55 validAccesses: 256 @@ -487,12 +397,9 @@ dn: CN=Refresh-Group-Cache,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Refresh-Group-Cache -instanceType: 4 displayName: Refresh Group Cache for Logons -showInAdvancedViewOnly: TRUE rightsGuid: 9432c620-033c-4db7-8b58-14ef6d0bf477 appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 56 validAccesses: 256 @@ -500,12 +407,9 @@ dn: CN=SAM-Enumerate-Entire-Domain,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: SAM-Enumerate-Entire-Domain -instanceType: 4 displayName: Enumerate Entire SAM Domain -showInAdvancedViewOnly: TRUE rightsGuid: 91d67418-0135-4acc-8d79-c08e857cfbec appliesTo: bf967aad-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 57 validAccesses: 256 @@ -513,13 +417,10 @@ dn: CN=Generate-RSoP-Logging,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Generate-RSoP-Logging -instanceType: 4 displayName: Generate Resultant Set of Policy (Logging) -showInAdvancedViewOnly: TRUE rightsGuid: b7b1b3de-ab09-4242-9e30-9980e5d322f7 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 appliesTo: bf967aa5-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 58 validAccesses: 256 @@ -527,12 +428,9 @@ dn: CN=Domain-Other-Parameters,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Domain-Other-Parameters -instanceType: 4 displayName: Other Domain Parameters (for use by SAM) -showInAdvancedViewOnly: TRUE rightsGuid: b8119fd0-04f6-4762-ab7a-4986c76b3f9a appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 59 validAccesses: 48 @@ -540,12 +438,9 @@ dn: CN=DNS-Host-Name-Attributes,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DNS-Host-Name-Attributes -instanceType: 4 displayName: DNS Host Name Attributes -showInAdvancedViewOnly: TRUE rightsGuid: 72e39547-7b18-11d1-adef-00c04fd8d5cd appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 60 validAccesses: 48 @@ -553,12 +448,9 @@ dn: CN=Create-Inbound-Forest-Trust,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Create-Inbound-Forest-Trust -instanceType: 4 displayName: Create Inbound Forest Trust -showInAdvancedViewOnly: TRUE rightsGuid: e2a36dc9-ae17-47c3-b58b-be34c55ba633 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 61 validAccesses: 256 @@ -566,14 +458,11 @@ dn: CN=DS-Replication-Get-Changes-All,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Replication-Get-Changes-All -instanceType: 4 displayName: Replicating Directory Changes All -showInAdvancedViewOnly: TRUE rightsGuid: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 62 validAccesses: 256 @@ -581,12 +470,9 @@ dn: CN=Migrate-SID-History,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Migrate-SID-History -instanceType: 4 displayName: Migrate SID History -showInAdvancedViewOnly: TRUE rightsGuid: BA33815A-4F93-4c76-87F3-57574BFF8109 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 63 validAccesses: 256 @@ -594,14 +480,11 @@ dn: CN=Reanimate-Tombstones,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Reanimate-Tombstones -instanceType: 4 displayName: Reanimate Tombstones -showInAdvancedViewOnly: TRUE rightsGuid: 45EC5156-DB7E-47bb-B53F-DBEB2D03C40F appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 64 validAccesses: 256 @@ -609,14 +492,11 @@ dn: CN=Allowed-To-Authenticate,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Allowed-To-Authenticate -instanceType: 4 displayName: Allowed to Authenticate -showInAdvancedViewOnly: TRUE rightsGuid: 68B1D179-0D15-4d4f-AB71-46152E79A7BC appliesTo: 4828cc14-1437-45bc-9b07-ad6f015e5f28 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 65 validAccesses: 256 @@ -624,12 +504,9 @@ dn: CN=DS-Execute-Intentions-Script,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Execute-Intentions-Script -instanceType: 4 displayName: Execute Forest Update Script -showInAdvancedViewOnly: TRUE rightsGuid: 2f16c4a5-b98e-432c-952a-cb388ba33f2e appliesTo: ef9e60e0-56f7-11d1-a9c6-0000f80367c1 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 66 validAccesses: 256 @@ -637,14 +514,11 @@ dn: CN=DS-Replication-Monitor-Topology,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Replication-Monitor-Topology -instanceType: 4 displayName: Monitor Active Directory Replication -showInAdvancedViewOnly: TRUE rightsGuid: f98340fb-7c5b-4cdb-a00b-2ebdfa115a96 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 67 validAccesses: 256 @@ -652,12 +526,9 @@ dn: CN=Update-Password-Not-Required-Bit,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Update-Password-Not-Required-Bit -instanceType: 4 displayName: Update Password Not Required Bit -showInAdvancedViewOnly: TRUE rightsGuid: 280f369c-67c7-438e-ae98-1d46f3c6f541 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 68 validAccesses: 256 @@ -665,12 +536,9 @@ dn: CN=Unexpire-Password,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Unexpire-Password -instanceType: 4 displayName: Unexpire Password -showInAdvancedViewOnly: TRUE rightsGuid: ccc2dc7d-a6ad-4a7a-8846-c04e3cc53501 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 69 validAccesses: 256 @@ -678,12 +546,9 @@ dn: CN=Enable-Per-User-Reversibly-Encrypted-Password,CN=Extended-Rights,${CONFIG objectClass: top objectClass: controlAccessRight cn: Enable-Per-User-Reversibly-Encrypted-Password -instanceType: 4 displayName: Enable Per User Reversibly Encrypted Password -showInAdvancedViewOnly: TRUE rightsGuid: 05c74c5e-4deb-43b4-bd9f-86664c2a7fd5 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 70 validAccesses: 256 @@ -691,12 +556,9 @@ dn: CN=DS-Query-Self-Quota,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Query-Self-Quota -instanceType: 4 displayName: Query Self Quota -showInAdvancedViewOnly: TRUE rightsGuid: 4ecc03fe-ffc0-4947-b630-eb672a8a9dbc appliesTo: da83fc4f-076f-4aea-b4dc-8f4dab9b5993 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 71 validAccesses: 256 @@ -704,12 +566,9 @@ dn: CN=Domain-Administer-Server,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Domain-Administer-Server -instanceType: 4 displayName: Domain Administer Server -showInAdvancedViewOnly: TRUE rightsGuid: ab721a52-1e2f-11d0-9819-00aa0040529b appliesTo: bf967aad-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 1 validAccesses: 256 @@ -717,14 +576,11 @@ dn: CN=User-Change-Password,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: User-Change-Password -instanceType: 4 displayName: Change Password -showInAdvancedViewOnly: TRUE rightsGuid: ab721a53-1e2f-11d0-9819-00aa0040529b appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 2 validAccesses: 256 @@ -732,14 +588,11 @@ dn: CN=User-Force-Change-Password,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: User-Force-Change-Password -instanceType: 4 displayName: Reset Password -showInAdvancedViewOnly: TRUE rightsGuid: 00299570-246d-11d0-a768-00aa006e0529 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 3 validAccesses: 256 @@ -747,14 +600,11 @@ dn: CN=Send-As,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Send-As -instanceType: 4 displayName: Send As -showInAdvancedViewOnly: TRUE rightsGuid: ab721a54-1e2f-11d0-9819-00aa0040529b appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 4 validAccesses: 256 @@ -762,14 +612,11 @@ dn: CN=Receive-As,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Receive-As -instanceType: 4 displayName: Receive As -showInAdvancedViewOnly: TRUE rightsGuid: ab721a56-1e2f-11d0-9819-00aa0040529b appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 5 validAccesses: 256 @@ -777,12 +624,9 @@ dn: CN=Send-To,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Send-To -instanceType: 4 displayName: Send To -showInAdvancedViewOnly: TRUE rightsGuid: ab721a55-1e2f-11d0-9819-00aa0040529b appliesTo: bf967a9c-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 6 validAccesses: 256 @@ -790,13 +634,10 @@ dn: CN=Domain-Password,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Domain-Password -instanceType: 4 displayName: Domain Password & Lockout Policies -showInAdvancedViewOnly: TRUE rightsGuid: c7407360-20bf-11d0-a768-00aa006e0529 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 appliesTo: 19195a5a-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 7 validAccesses: 48 @@ -804,13 +645,10 @@ dn: CN=General-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: General-Information -instanceType: 4 displayName: General Information -showInAdvancedViewOnly: TRUE rightsGuid: 59ba2f42-79a2-11d0-9020-00c04fc2d3cf appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 8 validAccesses: 48 @@ -818,14 +656,11 @@ dn: CN=User-Account-Restrictions,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: User-Account-Restrictions -instanceType: 4 displayName: Account Restrictions -showInAdvancedViewOnly: TRUE rightsGuid: 4c164200-20c0-11d0-a768-00aa006e0529 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 9 validAccesses: 48 @@ -833,13 +668,10 @@ dn: CN=User-Logon,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: User-Logon -instanceType: 4 displayName: Logon Information -showInAdvancedViewOnly: TRUE rightsGuid: 5f202010-79a5-11d0-9020-00c04fc2d4cf appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 10 validAccesses: 48 @@ -847,13 +679,10 @@ dn: CN=Membership,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Membership -instanceType: 4 displayName: Group Membership -showInAdvancedViewOnly: TRUE rightsGuid: bc0ac240-79a9-11d0-9020-00c04fc2d4cf appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 11 validAccesses: 48 @@ -861,12 +690,9 @@ dn: CN=Open-Address-Book,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Open-Address-Book -instanceType: 4 displayName: Open Address List -showInAdvancedViewOnly: TRUE rightsGuid: a1990816-4298-11d1-ade2-00c04fd8d5cd appliesTo: 3e74f60f-3e73-11d1-a9c0-0000f80367c1 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 21 validAccesses: 256 @@ -874,15 +700,12 @@ dn: CN=Personal-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Personal-Information -instanceType: 4 displayName: Personal Information -showInAdvancedViewOnly: TRUE rightsGuid: 77B5B886-944A-11d1-AEBD-0000F80367C1 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: 5cb41ed0-0e4c-11d0-a286-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 23 validAccesses: 48 @@ -890,14 +713,11 @@ dn: CN=Email-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Email-Information -instanceType: 4 displayName: Phone and Mail Options -showInAdvancedViewOnly: TRUE rightsGuid: E45795B2-9455-11d1-AEBD-0000F80367C1 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a9c-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 22 validAccesses: 48 @@ -905,14 +725,11 @@ dn: CN=Web-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Web-Information -instanceType: 4 displayName: Web Information -showInAdvancedViewOnly: TRUE rightsGuid: E45795B3-9455-11d1-AEBD-0000F80367C1 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: 5cb41ed0-0e4c-11d0-a286-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 24 validAccesses: 48 @@ -920,14 +737,11 @@ dn: CN=DS-Replication-Get-Changes,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Replication-Get-Changes -instanceType: 4 displayName: Replicating Directory Changes -showInAdvancedViewOnly: TRUE rightsGuid: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 25 validAccesses: 256 @@ -935,14 +749,11 @@ dn: CN=DS-Replication-Synchronize,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Replication-Synchronize -instanceType: 4 displayName: Replication Synchronization -showInAdvancedViewOnly: TRUE rightsGuid: 1131f6ab-9c07-11d1-f79f-00c04fc2dcd2 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 26 validAccesses: 256 @@ -950,14 +761,11 @@ dn: CN=DS-Replication-Manage-Topology,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Replication-Manage-Topology -instanceType: 4 displayName: Manage Replication Topology -showInAdvancedViewOnly: TRUE rightsGuid: 1131f6ac-9c07-11d1-f79f-00c04fc2dcd2 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 27 validAccesses: 256 @@ -965,11 +773,8 @@ dn: CN=Change-Schema-Master,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Change-Schema-Master -instanceType: 4 displayName: Change Schema Master -showInAdvancedViewOnly: TRUE rightsGuid: e12b56b6-0a95-11d1-adbb-00c04fd8d5cd appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 28 validAccesses: 256 -- cgit From c9b6e9fd038e1fe42c30d27939893c12ecee5776 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Thu, 28 May 2009 20:02:42 -0500 Subject: s4: Add additional well-known SID's/RID's. Information was found at http://support.microsoft.com/kb/243330 Not all well-known identifiers were included - only those necessary for enhancing the 2-letter mappings used in SDDL strings were added. --- librpc/gen_ndr/security.h | 4 ++++ librpc/idl/security.idl | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/librpc/gen_ndr/security.h b/librpc/gen_ndr/security.h index 9db2108f82..d1dcbe552a 100644 --- a/librpc/gen_ndr/security.h +++ b/librpc/gen_ndr/security.h @@ -121,17 +121,21 @@ #define SID_BUILTIN_REPLICATOR ( "S-1-5-32-552" ) #define SID_BUILTIN_RAS_SERVERS ( "S-1-5-32-553" ) #define SID_BUILTIN_PREW2K ( "S-1-5-32-554" ) +#define SID_BUILTIN_REMOTE_DESKTOP_USERS ( "S-1-5-32-555" ) +#define SID_BUILTIN_NETWORK_CONF_OPERATORS ( "S-1-5-32-556" ) #define DOMAIN_RID_LOGON ( 9 ) #define DOMAIN_RID_ADMINISTRATOR ( 500 ) #define DOMAIN_RID_GUEST ( 501 ) #define DOMAIN_RID_KRBTGT ( 502 ) #define DOMAIN_RID_ADMINS ( 512 ) #define DOMAIN_RID_USERS ( 513 ) +#define DOMAIN_RID_GUESTS ( 514 ) #define DOMAIN_RID_DOMAIN_MEMBERS ( 515 ) #define DOMAIN_RID_DCS ( 516 ) #define DOMAIN_RID_CERT_ADMINS ( 517 ) #define DOMAIN_RID_SCHEMA_ADMINS ( 518 ) #define DOMAIN_RID_ENTERPRISE_ADMINS ( 519 ) +#define DOMAIN_RID_POLICY_ADMINS ( 520 ) #define NT4_ACL_REVISION ( SECURITY_ACL_REVISION_NT4 ) #define SD_REVISION ( SECURITY_DESCRIPTOR_REVISION_1 ) struct dom_sid { diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl index 941883f644..9728c7fb07 100644 --- a/librpc/idl/security.idl +++ b/librpc/idl/security.idl @@ -219,6 +219,8 @@ interface security const string SID_BUILTIN_REPLICATOR = "S-1-5-32-552"; const string SID_BUILTIN_RAS_SERVERS = "S-1-5-32-553"; const string SID_BUILTIN_PREW2K = "S-1-5-32-554"; + const string SID_BUILTIN_REMOTE_DESKTOP_USERS = "S-1-5-32-555"; + const string SID_BUILTIN_NETWORK_CONF_OPERATORS = "S-1-5-32-556"; /* well-known domain RIDs */ const int DOMAIN_RID_LOGON = 9; @@ -227,11 +229,13 @@ interface security const int DOMAIN_RID_KRBTGT = 502; const int DOMAIN_RID_ADMINS = 512; const int DOMAIN_RID_USERS = 513; + const int DOMAIN_RID_GUESTS = 514; const int DOMAIN_RID_DOMAIN_MEMBERS = 515; const int DOMAIN_RID_DCS = 516; const int DOMAIN_RID_CERT_ADMINS = 517; const int DOMAIN_RID_SCHEMA_ADMINS = 518; const int DOMAIN_RID_ENTERPRISE_ADMINS = 519; + const int DOMAIN_RID_POLICY_ADMINS = 520; /* -- cgit From 554923ce1b1a3ab3a05bed14c0a2795e0c13febd Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Thu, 28 May 2009 20:18:33 -0500 Subject: s4: Add additional 2-letter SID/RID mappings. Information from http://msdn.microsoft.com/en-us/library/aa379602(VS.85).aspx --- source4/libcli/security/sddl.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index a8d893f085..39bdf047ac 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -80,11 +80,34 @@ static const struct { { "CO", SID_CREATOR_OWNER }, { "CG", SID_CREATOR_GROUP }, + { "AN", SID_NT_ANONYMOUS }, + { "BG", SID_BUILTIN_GUESTS }, + { "BO", SID_BUILTIN_BACKUP_OPERATORS }, + { "BU", SID_BUILTIN_USERS }, + { "IU", SID_NT_INTERACTIVE }, + { "LS", SID_NT_LOCAL_SERVICE }, + { "NO", SID_BUILTIN_NETWORK_CONF_OPERATORS }, + { "NS", SID_NT_NETWORK_SERVICE }, + { "NU", SID_NT_NETWORK }, + { "PU", SID_BUILTIN_POWER_USERS }, + { "RC", SID_NT_RESTRICTED }, + { "RD", SID_BUILTIN_REMOTE_DESKTOP_USERS }, + { "RE", SID_BUILTIN_REPLICATOR }, + { "SO", SID_BUILTIN_ACCOUNT_OPERATORS }, + { "SU", SID_NT_SERVICE }, + { "DA", NULL, DOMAIN_RID_ADMINS }, { "EA", NULL, DOMAIN_RID_ENTERPRISE_ADMINS }, { "DD", NULL, DOMAIN_RID_DCS }, { "DU", NULL, DOMAIN_RID_USERS }, { "CA", NULL, DOMAIN_RID_CERT_ADMINS }, + + { "DC", NULL, DOMAIN_RID_DOMAIN_MEMBERS }, + { "DG", NULL, DOMAIN_RID_GUESTS }, + { "LA", NULL, DOMAIN_RID_ADMINISTRATOR }, + { "LG", NULL, DOMAIN_RID_GUEST }, + { "PA", NULL, DOMAIN_RID_POLICY_ADMINS }, + { "SA", NULL, DOMAIN_RID_SCHEMA_ADMINS }, }; /* -- cgit From b83f84c8c3be1ce0319a9f36704e3bf4718e159f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 May 2009 17:02:19 +1000 Subject: s4:torture Don't try to Close a Deleted handle --- source4/torture/rpc/samr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index d9e4205e93..0072a018c8 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -6284,8 +6284,6 @@ static bool test_ManyObjects(struct dcerpc_pipe *p, default: return false; } - - ret &= test_samr_handle_Close(p, tctx, &handles[i]); } talloc_free(handles); -- cgit From 227553f904186112e9218c4a7c8b1b46fef5b897 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 May 2009 17:12:06 +1000 Subject: Win2k3 don't allow creating of domain trust accounts over SAMR --- source4/rpc_server/samr/dcesrv_samr.c | 10 +++++----- source4/torture/rpc/samr.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index fabc88d02d..ec60ac7a45 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -1213,6 +1213,9 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL if (d_state->builtin) { DEBUG(5, ("Cannot create a user in the BUILTIN domain")); return NT_STATUS_ACCESS_DENIED; + } else if (r->in.acct_flags == ACB_DOMTRUST) { + /* Domain trust accounts must be created by the LSA calls */ + return NT_STATUS_ACCESS_DENIED; } account_name = r->in.account_name->string; @@ -1258,6 +1261,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL } else if (r->in.acct_flags == ACB_WSTRUST) { if (cn_name[cn_name_len - 1] != '$') { + ldb_transaction_cancel(d_state->sam_ctx); return NT_STATUS_FOOBAR; } cn_name[cn_name_len - 1] = '\0'; @@ -1267,17 +1271,13 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL } else if (r->in.acct_flags == ACB_SVRTRUST) { if (cn_name[cn_name_len - 1] != '$') { + ldb_transaction_cancel(d_state->sam_ctx); return NT_STATUS_FOOBAR; } cn_name[cn_name_len - 1] = '\0'; container = "OU=Domain Controllers"; obj_class = "computer"; samdb_msg_add_int(d_state->sam_ctx, mem_ctx, msg, "primaryGroupID", DOMAIN_RID_DCS); - - } else if (r->in.acct_flags == ACB_DOMTRUST) { - container = "CN=Users"; - obj_class = "user"; - } else { ldb_transaction_cancel(d_state->sam_ctx); return NT_STATUS_INVALID_PARAMETER; diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 0072a018c8..a1a60bf5b4 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -4372,7 +4372,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK }, { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER }, { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER }, - { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK }, + { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED }, { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER }, { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER }, { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER }, -- cgit From f6535d3f3f60bf60806795e55ba09ba6d5bcd9a3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 29 May 2009 09:42:31 +0200 Subject: Fix some nonempty blank lines --- source4/ldap_server/ldap_server.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index a924024160..38858efc7c 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -6,17 +6,17 @@ Copyright (C) Andrew Tridgell 2005 Copyright (C) Volker Lendecke 2004 Copyright (C) Stefan Metzmacher 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 3 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, see . */ @@ -77,20 +77,20 @@ static void ldapsrv_process_message(struct ldapsrv_connection *conn, ldapsrv_terminate_connection(conn, "no memory"); return; } - + call->request = talloc_steal(call, msg); call->conn = conn; call->replies = NULL; call->send_callback = NULL; call->send_private = NULL; - + /* make the call */ status = ldapsrv_do_call(call); if (!NT_STATUS_IS_OK(status)) { talloc_free(call); return; } - + blob = data_blob(NULL, 0); if (call->replies == NULL) { @@ -210,7 +210,7 @@ static void ldapsrv_send(struct stream_connection *c, uint16_t flags) { struct ldapsrv_connection *conn = talloc_get_type(c->private_data, struct ldapsrv_connection); - + packet_queue_run(conn->packet); } @@ -294,7 +294,7 @@ static int ldapsrv_load_limits(struct ldapsrv_connection *conn) s = sscanf((const char *)el->values[i].data, "%255[^=]=%d", policy_name, &policy_value); if (ret != 2 || policy_value == 0) continue; - + if (strcasecmp("InitRecvTimeout", policy_name) == 0) { conn->limits.initial_timeout = policy_value; continue; @@ -390,7 +390,7 @@ static void ldapsrv_accept(struct stream_connection *c) if (conn->sockets.tls) { packet_set_unreliable_select(conn->packet); } - + /* Ensure we don't get packets until the database is ready below */ packet_recv_disable(conn->packet); @@ -399,7 +399,7 @@ static void ldapsrv_accept(struct stream_connection *c) stream_terminate_connection(c, "Failed to init server credentials\n"); return; } - + cli_credentials_set_conf(server_credentials, conn->lp_ctx); status = cli_credentials_set_machine_account(server_credentials, conn->lp_ctx); if (!NT_STATUS_IS_OK(status)) { @@ -483,7 +483,7 @@ static NTSTATUS add_socket(struct tevent_context *event_context, if (!ldb) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } - + if (samdb_is_gc(ldb)) { port = 3268; status = stream_setup_socket(event_context, lp_ctx, -- cgit From 2228cc6a0f942b774bef7fb0b99009897fa4dff4 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Fri, 29 May 2009 09:49:49 +0200 Subject: s3/docs: Fix typo. This fixes bug #4341. Thanks to Michael Cartmell for reporting! Karolin --- docs-xml/Samba3-HOWTO/TOSHARG-VFS.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-xml/Samba3-HOWTO/TOSHARG-VFS.xml b/docs-xml/Samba3-HOWTO/TOSHARG-VFS.xml index b8bd3277a6..91e9712cb5 100644 --- a/docs-xml/Samba3-HOWTO/TOSHARG-VFS.xml +++ b/docs-xml/Samba3-HOWTO/TOSHARG-VFS.xml @@ -276,7 +276,7 @@ quotasettings: gid nolimit = no logging - This auditing tool is more felxible than most people readily will recognize. There are a number of ways + This auditing tool is more flexible than most people will readily recognize. There are a number of ways by which useful logging information can be recorded. -- cgit From 1a7898e3a8f2c2e2cacd645b97da88054df931ae Mon Sep 17 00:00:00 2001 From: Kumar Thangavelu Date: Fri, 29 May 2009 11:27:38 +0200 Subject: s3/getdcname: Fix 'net' crash. 'net' command crashed when attempting to join a domain. This occurred in a very specific case where the DC had multiple IPs and one of the IPs was invalid. Signed-off-by: Volker Lendecke --- source3/libsmb/dsgetdcname.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 5606b8e7c9..fb87b4dc9a 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -626,8 +626,8 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, struct ip_service_name *r = &dclist[count]; - r->port = dcs[count].port; - r->hostname = dcs[count].hostname; + r->port = dcs[i].port; + r->hostname = dcs[i].hostname; /* If we don't have an IP list for a name, lookup it up */ -- cgit From 9bd8b0a15773d3d5c0649bfb49bb16acfb4bb5f1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 12:41:41 +0200 Subject: s3-rpc_server: increase max number of open policy handles per pipe to 2048. Guenther --- source3/rpc_server/srv_lsa_hnd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c index d8c48058be..94e73fb54d 100644 --- a/source3/rpc_server/srv_lsa_hnd.c +++ b/source3/rpc_server/srv_lsa_hnd.c @@ -46,7 +46,7 @@ struct handle_list { /* This is the max handles across all instances of a pipe name. */ #ifndef MAX_OPEN_POLS -#define MAX_OPEN_POLS 1024 +#define MAX_OPEN_POLS 2048 #endif /**************************************************************************** -- cgit From 65f86a644a8171a99c63b6cb32e01e22897174f6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 12:42:15 +0200 Subject: s3-netlogon: return proper error code for unsupported validation class. Guenther --- source3/rpc_server/srv_netlog_nt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 333eabe2ce..73d1f4b1a5 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -893,7 +893,7 @@ NTSTATUS _netr_LogonSamLogon(pipes_struct *p, if (r->in.validation_level != 2 && r->in.validation_level != 3) { DEBUG(0,("%s: bad validation_level value %d.\n", fn, (int)r->in.validation_level)); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_INVALID_INFO_CLASS; } if (process_creds) { -- cgit From 90b38906541de554e3964d96ed83a7c71b5ea05c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 13:15:27 +0200 Subject: s3-netlogon: Fix _netr_LogonSamLogon{Ex} with validation level != 3. Guenther --- source3/rpc_server/srv_netlog_nt.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 73d1f4b1a5..7f45a4809c 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -882,6 +882,13 @@ NTSTATUS _netr_LogonSamLogon(pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } + *r->out.authoritative = true; /* authoritative response */ + if (r->in.validation_level != 2 && r->in.validation_level != 3) { + DEBUG(0,("%s: bad validation_level value %d.\n", + fn, (int)r->in.validation_level)); + return NT_STATUS_INVALID_INFO_CLASS; + } + sam3 = TALLOC_ZERO_P(p->mem_ctx, struct netr_SamInfo3); if (!sam3) { return NT_STATUS_NO_MEMORY; @@ -889,12 +896,6 @@ NTSTATUS _netr_LogonSamLogon(pipes_struct *p, /* store the user information, if there is any. */ r->out.validation->sam3 = sam3; - *r->out.authoritative = true; /* authoritative response */ - if (r->in.validation_level != 2 && r->in.validation_level != 3) { - DEBUG(0,("%s: bad validation_level value %d.\n", - fn, (int)r->in.validation_level)); - return NT_STATUS_INVALID_INFO_CLASS; - } if (process_creds) { -- cgit From 059401e4575922ee23656b880c2c2ef230a7cebe Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 13:16:25 +0200 Subject: s4-smbtorture: Fix test_SamLogon() for netlogon servers not yet supporting validation level 6. Guenther --- source4/torture/rpc/samr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index a1a60bf5b4..55fbb44828 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -2745,6 +2745,10 @@ static bool test_SamLogon(struct torture_context *tctx, r.in.validation_level = 6; status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r); + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) { + r.in.validation_level = 3; + status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r); + } if (!NT_STATUS_IS_OK(status)) { torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed"); return true; -- cgit From 12496ea5aba3a53691ca74f12192f489d7831592 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 13:18:23 +0200 Subject: s4-smbtorture: remove trailing whitespace. Guenther --- source4/torture/rpc/samr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 55fbb44828..30e7e0889c 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -2674,7 +2674,7 @@ static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p, } static bool test_SamLogon(struct torture_context *tctx, - struct dcerpc_pipe *p, + struct dcerpc_pipe *p, struct cli_credentials *test_credentials, NTSTATUS expected_result) { @@ -2908,7 +2908,7 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p, b->flags &= ~DCERPC_AUTH_OPTIONS; b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128; - status = dcerpc_pipe_connect_b(tctx, &np, b, + status = dcerpc_pipe_connect_b(tctx, &np, b, &ndr_table_netlogon, machine_credentials, tctx->ev, tctx->lp_ctx); @@ -6181,7 +6181,7 @@ static bool test_ManyObjects(struct dcerpc_pipe *p, uint32_t i; struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total); - + /* query */ { -- cgit From bff54b90c353920ba058cc53a6cc0464f0939424 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 28 May 2009 16:08:04 +0200 Subject: util: move add_gid_to_array_unique to toplevel and add add_uid_to_array_unique. Guenther --- lib/util/config.mk | 3 +- lib/util/util.h | 12 ++++++ lib/util/util_id.c | 88 ++++++++++++++++++++++++++++++++++++++++++ source3/Makefile.in | 2 +- source3/include/proto.h | 2 - source3/lib/util.c | 33 ---------------- source3/passdb/pdb_interface.c | 20 ---------- 7 files changed, 103 insertions(+), 57 deletions(-) create mode 100644 lib/util/util_id.c diff --git a/lib/util/config.mk b/lib/util/config.mk index 1b620d1464..3ae8a22780 100644 --- a/lib/util/config.mk +++ b/lib/util/config.mk @@ -28,7 +28,8 @@ LIBSAMBA-UTIL_OBJ_FILES = $(addprefix $(libutilsrcdir)/, \ rbtree.o \ talloc_stack.o \ smb_threads.o \ - params.o) + params.o \ + util_id.o) PUBLIC_HEADERS += $(addprefix $(libutilsrcdir)/, util.h \ dlinklist.h \ diff --git a/lib/util/util.h b/lib/util/util.h index dab5ff9360..20050d2f0a 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -817,4 +817,16 @@ bool unmap_file(void *start, size_t size); void print_asc(int level, const uint8_t *buf,int len); +/** + * Add an id to an array of ids. + * + * num should be a pointer to an integer that holds the current + * number of elements in ids. It will be updated by this function. + */ + +bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx, uid_t uid, + uid_t **uids, size_t *num_uids); +bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid, + gid_t **gids, size_t *num_gids); + #endif /* _SAMBA_UTIL_H_ */ diff --git a/lib/util/util_id.c b/lib/util/util_id.c new file mode 100644 index 0000000000..8744ce4e4e --- /dev/null +++ b/lib/util/util_id.c @@ -0,0 +1,88 @@ +/* + Unix SMB/CIFS implementation. + + Helper routines for uid and gid arrays + + Copyright (C) Guenther Deschner 2009 + + 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 3 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, see . +*/ + +#include "includes.h" + +/**************************************************************************** + Add a gid to an array of gids if it's not already there. +****************************************************************************/ + +bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid, + gid_t **gids, size_t *num_gids) +{ + int i; + + if ((*num_gids != 0) && (*gids == NULL)) { + /* + * A former call to this routine has failed to allocate memory + */ + return false; + } + + for (i=0; i<*num_gids; i++) { + if ((*gids)[i] == gid) { + return true; + } + } + + *gids = talloc_realloc(mem_ctx, *gids, gid_t, *num_gids+1); + if (*gids == NULL) { + *num_gids = 0; + return false; + } + + (*gids)[*num_gids] = gid; + *num_gids += 1; + return true; +} + +/**************************************************************************** + Add a uid to an array of uids if it's not already there. +****************************************************************************/ + +bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx, uid_t uid, + uid_t **uids, size_t *num_uids) +{ + int i; + + if ((*num_uids != 0) && (*uids == NULL)) { + /* + * A former call to this routine has failed to allocate memory + */ + return false; + } + + for (i=0; i<*num_uids; i++) { + if ((*uids)[i] == uid) { + return true; + } + } + + *uids = talloc_realloc(mem_ctx, *uids, uid_t, *num_uids+1); + if (*uids == NULL) { + *num_uids = 0; + return false; + } + + (*uids)[*num_uids] = uid; + *num_uids += 1; + return true; +} diff --git a/source3/Makefile.in b/source3/Makefile.in index c7514a0b1d..72fce60faa 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -355,7 +355,7 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \ ../lib/util/genrand.o ../lib/util/util_net.o \ ../lib/util/become_daemon.o ../lib/util/system.o \ ../lib/util/tevent_unix.o ../lib/util/tevent_ntstatus.o \ - ../lib/util/smb_threads.o + ../lib/util/smb_threads.o ../lib/util/util_id.o CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \ ../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index 4713bd713a..7d297f6c32 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1088,8 +1088,6 @@ struct user_auth_info *get_cmdline_auth_info_copy(TALLOC_CTX *mem_ctx, const struct user_auth_info *info); bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_info); void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info); -bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid, - gid_t **gids, size_t *num_gids); bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf); bool socket_exist(const char *fname); bool directory_exist_stat(char *dname,SMB_STRUCT_STAT *st); diff --git a/source3/lib/util.c b/source3/lib/util.c index 8e67edeae6..b85f29e136 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -495,39 +495,6 @@ void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info) TALLOC_FREE(frame); } -/**************************************************************************** - Add a gid to an array of gids if it's not already there. -****************************************************************************/ - -bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid, - gid_t **gids, size_t *num_gids) -{ - int i; - - if ((*num_gids != 0) && (*gids == NULL)) { - /* - * A former call to this routine has failed to allocate memory - */ - return False; - } - - for (i=0; i<*num_gids; i++) { - if ((*gids)[i] == gid) { - return True; - } - } - - *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1); - if (*gids == NULL) { - *num_gids = 0; - return False; - } - - (*gids)[*num_gids] = gid; - *num_gids += 1; - return True; -} - /******************************************************************* Check if a file exists - call vfs_file_exist for samba files. ********************************************************************/ diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index b4e1bd436c..b69e41590f 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1330,26 +1330,6 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, return ret; } -static bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx, - uid_t uid, uid_t **pp_uids, size_t *p_num) -{ - size_t i; - - for (i=0; i<*p_num; i++) { - if ((*pp_uids)[i] == uid) - return True; - } - - *pp_uids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_uids, uid_t, *p_num+1); - - if (*pp_uids == NULL) - return False; - - (*pp_uids)[*p_num] = uid; - *p_num += 1; - return True; -} - static bool get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size_t *p_num) { struct group *grp; -- cgit From 36fc0b961f32d6fd978f293731a5e2cb01a6154f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 28 May 2009 16:13:33 +0200 Subject: s4-smbtorture: add a very basic NSS-WRAPPER testsuite. Guenther --- lib/nss_wrapper/testsuite.c | 219 ++++++++++++++++++++++++++++++++++++++++ source4/torture/local/config.mk | 4 +- source4/torture/local/local.c | 1 + 3 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 lib/nss_wrapper/testsuite.c diff --git a/lib/nss_wrapper/testsuite.c b/lib/nss_wrapper/testsuite.c new file mode 100644 index 0000000000..2a9cfaa391 --- /dev/null +++ b/lib/nss_wrapper/testsuite.c @@ -0,0 +1,219 @@ +/* + Unix SMB/CIFS implementation. + + local testing of the nss wrapper + + Copyright (C) Guenther Deschner 2009 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "torture/torture.h" +#include "lib/replace/system/passwd.h" +#include "lib/nss_wrapper/nss_wrapper.h" + +static void print_passwd(struct passwd *pwd) +{ + printf("%s:%s:%lu:%lu:%s:%s:%s\n", + pwd->pw_name, + pwd->pw_passwd, + (unsigned long)pwd->pw_uid, + (unsigned long)pwd->pw_gid, + pwd->pw_gecos, + pwd->pw_dir, + pwd->pw_shell); +} + + +static bool test_nwrap_getpwnam(struct torture_context *tctx, + const char *name) +{ + struct passwd *pwd; + + torture_comment(tctx, "Testing getpwnam: %s\n", name); + + pwd = getpwnam(name); + if (pwd) { + print_passwd(pwd); + } + + return pwd ? true : false; +} + +static bool test_nwrap_getpwuid(struct torture_context *tctx, + uid_t uid) +{ + struct passwd *pwd; + + torture_comment(tctx, "Testing getpwuid: %lu\n", (unsigned long)uid); + + pwd = getpwuid(uid); + if (pwd) { + print_passwd(pwd); + } + + return pwd ? true : false; +} + +static void print_group(struct group *grp) +{ + int i; + printf("%s:%s:%lu:", + grp->gr_name, + grp->gr_passwd, + (unsigned long)grp->gr_gid); + + if (!grp->gr_mem[0]) { + printf("\n"); + return; + } + + for (i=0; grp->gr_mem[i+1]; i++) { + printf("%s,", grp->gr_mem[i]); + } + printf("%s\n", grp->gr_mem[i]); +} + +static bool test_nwrap_getgrnam(struct torture_context *tctx, + const char *name) +{ + struct group *grp; + + torture_comment(tctx, "Testing getgrnam: %s\n", name); + + grp = getgrnam(name); + if (grp) { + print_group(grp); + } + + return grp ? true : false; +} + +static bool test_nwrap_getgrgid(struct torture_context *tctx, + gid_t gid) +{ + struct group *grp; + + torture_comment(tctx, "Testing getgrgid: %lu\n", (unsigned long)gid); + + grp = getgrgid(gid); + if (grp) { + print_group(grp); + } + + return grp ? true : false; +} + + +static bool test_nwrap_passwd(struct torture_context *tctx) +{ + struct passwd *pwd; + const char **names = NULL; + uid_t *uids = NULL; + int num_names = 0; + size_t num_uids = 0; + int i; + + torture_comment(tctx, "Testing setpwent\n"); + setpwent(); + + while ((pwd = getpwent())) { + torture_comment(tctx, "Testing getpwent\n"); + + if (pwd) { + print_passwd(pwd); + add_string_to_array(tctx, pwd->pw_name, &names, &num_names); + add_uid_to_array_unique(tctx, pwd->pw_uid, &uids, &num_uids); + } + } + + torture_comment(tctx, "Testing endpwent\n"); + endpwent(); + + torture_assert_int_equal(tctx, num_names, num_uids, "invalid results"); + + for (i=0; i < num_names; i++) { + torture_assert(tctx, test_nwrap_getpwnam(tctx, names[i]), + "failed to call getpwnam for enumerated user"); + torture_assert(tctx, test_nwrap_getpwuid(tctx, uids[i]), + "failed to call getpwuid for enumerated user"); + } + + return true; +} + +static bool test_nwrap_group(struct torture_context *tctx) +{ + struct group *grp; + const char **names = NULL; + gid_t *gids = NULL; + int num_names = 0; + size_t num_gids = 0; + int i; + + torture_comment(tctx, "Testing setgrent\n"); + setgrent(); + + do { + torture_comment(tctx, "Testing getgrent\n"); + grp = getgrent(); + if (grp) { + print_group(grp); + add_string_to_array(tctx, grp->gr_name, &names, &num_names); + add_gid_to_array_unique(tctx, grp->gr_gid, &gids, &num_gids); + } + } while (grp); + + torture_comment(tctx, "Testing endgrent\n"); + endgrent(); + + torture_assert_int_equal(tctx, num_names, num_gids, "invalid results"); + + for (i=0; i < num_names; i++) { + torture_assert(tctx, test_nwrap_getgrnam(tctx, names[i]), + "failed to call getgrnam for enumerated user"); + torture_assert(tctx, test_nwrap_getgrgid(tctx, gids[i]), + "failed to call getgrgid for enumerated user"); + } + + return true; +} + +static bool test_nwrap_env(struct torture_context *tctx) +{ + const char *old_pwd = getenv("NSS_WRAPPER_PASSWD"); + const char *old_group = getenv("NSS_WRAPPER_GROUP"); + + if (!old_pwd || !old_group) { + torture_skip(tctx, "nothing to test\n"); + return true; + } + + torture_assert(tctx, test_nwrap_passwd(tctx), + "failed to test users"); + torture_assert(tctx, test_nwrap_group(tctx), + "failed to test groups"); + + return true; +} + +struct torture_suite *torture_local_nss_wrapper(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, "NSS-WRAPPER"); + + torture_suite_add_simple_test(suite, "env", test_nwrap_env); + + return suite; +} diff --git a/source4/torture/local/config.mk b/source4/torture/local/config.mk index 5c8c1d5762..28599e4bda 100644 --- a/source4/torture/local/config.mk +++ b/source4/torture/local/config.mk @@ -17,7 +17,8 @@ PRIVATE_DEPENDENCIES = \ TORTURE_LIBCRYPTO \ share \ torture_registry \ - PROVISION + PROVISION \ + NSS_WRAPPER # End SUBSYSTEM TORTURE_LOCAL ################################# @@ -34,6 +35,7 @@ TORTURE_LOCAL_OBJ_FILES = \ $(torturesrcdir)/../../lib/util/tests/idtree.o \ $(torturesrcdir)/../lib/socket/testsuite.o \ $(torturesrcdir)/../../lib/socket_wrapper/testsuite.o \ + $(torturesrcdir)/../../lib/nss_wrapper/testsuite.o \ $(torturesrcdir)/../libcli/resolve/testsuite.o \ $(torturesrcdir)/../../lib/util/tests/strlist.o \ $(torturesrcdir)/../../lib/util/tests/str.o \ diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c index a1b100edb8..73ee366dcd 100644 --- a/source4/torture/local/local.c +++ b/source4/torture/local/local.c @@ -43,6 +43,7 @@ torture_local_iconv, torture_local_socket, torture_local_socket_wrapper, + torture_local_nss_wrapper, torture_pac, torture_local_resolve, torture_local_sddl, -- cgit From 7b8d30d1bb6403183dceaaff987a8a96700bb942 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 28 May 2009 16:14:18 +0200 Subject: s3-selftest: enable LOCAL-NSS-WRAPPER test against samba 3. Guenther --- source3/script/tests/test_posix_s3.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh index 0bcf3695ed..83593dde4d 100755 --- a/source3/script/tests/test_posix_s3.sh +++ b/source3/script/tests/test_posix_s3.sh @@ -45,12 +45,14 @@ rpc="$rpc RPC-LSA-GETUSER RPC-LSA-LOOKUPSIDS RPC-LSA-LOOKUPNAMES" rpc="$rpc RPC-SAMR-USERS RPC-SAMR-USERS-PRIVILEGES RPC-SAMR-PASSWORDS RPC-SAMR-PASSWORDS-PWDLASTSET RPC-SAMR-LARGE-DC RPC-JOIN" rpc="$rpc RPC-SCHANNEL RPC-SCHANNEL2 RPC-BENCH-SCHANNEL1" +local="LOCAL-NSS-WRAPPER" + # NOTE: to enable the UNIX-WHOAMI test, we need to change the default share # config to allow guest access. I'm not sure whether this would break other # tests, so leaving it alone for now -- jpeach unix="UNIX-INFO2" -tests="$base $raw $rpc $unix" +tests="$base $raw $rpc $unix $local" if test "x$POSIX_SUBTESTS" != "x" ; then tests="$POSIX_SUBTESTS" -- cgit From fa3a6652211076772b1b24a3a2216014a16e4054 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 16:36:44 +0200 Subject: s4-smbtorture: add very basic LIBNETAPI testsuite. Guenther --- source3/samba4.m4 | 1 + source4/configure.ac | 1 + source4/torture/config.mk | 1 + source4/torture/libnetapi/config.m4 | 28 +++++++++++++ source4/torture/libnetapi/config.mk | 15 +++++++ source4/torture/libnetapi/libnetapi.c | 78 +++++++++++++++++++++++++++++++++++ source4/torture/torture.c | 1 + 7 files changed, 125 insertions(+) create mode 100644 source4/torture/libnetapi/config.m4 create mode 100644 source4/torture/libnetapi/config.mk create mode 100644 source4/torture/libnetapi/libnetapi.c diff --git a/source3/samba4.m4 b/source3/samba4.m4 index 9e86f3fb1f..6b7c140bc1 100644 --- a/source3/samba4.m4 +++ b/source3/samba4.m4 @@ -128,6 +128,7 @@ SMB_INCLUDE_MK(lib/ldb/python.mk) SMB_ENABLE(swig_ldb,YES) m4_include(lib/tls/config.m4) +m4_include(torture/libnetapi/config.m4) dnl m4_include(auth/kerberos/config.m4) m4_include(auth/gensec/config.m4) diff --git a/source4/configure.ac b/source4/configure.ac index 82dd1346da..943a7c4345 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -99,6 +99,7 @@ SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = LDB_REQUIRED_VERSION, SMB_INCLUDE_MK(lib/ldb/python.mk) m4_include(lib/tls/config.m4) +m4_include(torture/libnetapi/config.m4) dnl m4_include(auth/kerberos/config.m4) m4_include(auth/gensec/config.m4) diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 72747a7886..dd1d5ea817 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -89,6 +89,7 @@ $(eval $(call proto_header_template,$(torturesrcdir)/raw/proto.h,$(TORTURE_RAW_O mkinclude smb2/config.mk mkinclude winbind/config.mk +mkinclude libnetapi/config.mk [SUBSYSTEM::TORTURE_NDR] PRIVATE_DEPENDENCIES = torture SERVICE_SMB diff --git a/source4/torture/libnetapi/config.m4 b/source4/torture/libnetapi/config.m4 new file mode 100644 index 0000000000..43724908ca --- /dev/null +++ b/source4/torture/libnetapi/config.m4 @@ -0,0 +1,28 @@ +############################### +# start SMB_EXT_LIB_NETAPI +# check for netapi.h and -lnetapi + +use_netapi=auto +AC_ARG_ENABLE(netapi, +AS_HELP_STRING([--enable-netapi],[Turn on netapi support (default=yes)]), + [if test x$enable_netapi = xno; then + use_netapi=no + fi]) + + +#if test x$use_netapi = xauto && pkg-config --exists netapi; then +# SMB_EXT_LIB_FROM_PKGCONFIG(NETAPI, netapi < 0.1, +# [use_netapi=yes], +# [use_netapi=no]) +#fi + +if test x$use_netapi = xauto; then + AC_CHECK_HEADERS(netapi.h) + AC_CHECK_LIB_EXT(netapi, NETAPI_LIBS, libnetapi_init) + if test x"$ac_cv_header_netapi_h" = x"yes" -a x"$ac_cv_lib_ext_netapi_libnetapi_init" = x"yes";then + SMB_ENABLE(NETAPI,YES) + else + SMB_ENABLE(TORTURE_LIBNETAPI,NO) + fi + SMB_EXT_LIB(NETAPI, $NETAPI_LIBS) +fi diff --git a/source4/torture/libnetapi/config.mk b/source4/torture/libnetapi/config.mk new file mode 100644 index 0000000000..ea4166c944 --- /dev/null +++ b/source4/torture/libnetapi/config.mk @@ -0,0 +1,15 @@ +################################# +# Start SUBSYSTEM TORTURE_LIBNETAPI +[MODULE::TORTURE_LIBNETAPI] +SUBSYSTEM = smbtorture +OUTPUT_TYPE = MERGED_OBJ +INIT_FUNCTION = torture_libnetapi_init +PRIVATE_DEPENDENCIES = \ + POPT_CREDENTIALS \ + NETAPI +# End SUBSYSTEM TORTURE_LIBNETAPI +################################# + +TORTURE_LIBNETAPI_OBJ_FILES = $(addprefix $(torturesrcdir)/libnetapi/, libnetapi.o) + +$(eval $(call proto_header_template,$(torturesrcdir)/libnetapi/proto.h,$(TORTURE_LIBNETAPI_OBJ_FILES:.o=.c))) diff --git a/source4/torture/libnetapi/libnetapi.c b/source4/torture/libnetapi/libnetapi.c new file mode 100644 index 0000000000..761a67ff22 --- /dev/null +++ b/source4/torture/libnetapi/libnetapi.c @@ -0,0 +1,78 @@ +/* + Unix SMB/CIFS implementation. + SMB torture tester + Copyright (C) Guenther Deschner 2009 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "torture/smbtorture.h" +#include "auth/credentials/credentials.h" +#include "lib/cmdline/popt_common.h" +#include +#include "torture/libnetapi/proto.h" + +bool torture_libnetapi_init_context(struct torture_context *tctx, + struct libnetapi_ctx **ctx_p) +{ + NET_API_STATUS status; + struct libnetapi_ctx *ctx; + + status = libnetapi_init(&ctx); + if (status != 0) { + return false; + } + + libnetapi_set_debuglevel(ctx, + talloc_asprintf(ctx, "%d", DEBUGLEVEL)); + libnetapi_set_username(ctx, + cli_credentials_get_username(cmdline_credentials)); + libnetapi_set_password(ctx, + cli_credentials_get_password(cmdline_credentials)); + + *ctx_p = ctx; + + return true; +} + +static bool torture_libnetapi_initialize(struct torture_context *tctx) +{ + NET_API_STATUS status; + struct libnetapi_ctx *ctx; + + status = libnetapi_init(&ctx); + if (status != 0) { + return false; + } + + libnetapi_free(ctx); + + return true; +} + +NTSTATUS torture_libnetapi_init(void) +{ + struct torture_suite *suite; + + suite = torture_suite_create(talloc_autofree_context(), "NETAPI"); + + torture_suite_add_simple_test(suite, "INITIALIZE", torture_libnetapi_initialize); + + suite->description = talloc_strdup(suite, "libnetapi convenience interface tests"); + + torture_register_suite(suite); + + return NT_STATUS_OK; +} diff --git a/source4/torture/torture.c b/source4/torture/torture.c index a9ec325dd6..de4fd591b9 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -57,6 +57,7 @@ _PUBLIC_ int torture_init(void) extern NTSTATUS torture_rpc_init(void); extern NTSTATUS torture_smb2_init(void); extern NTSTATUS torture_net_init(void); + extern NTSTATUS torture_libnetapi_init(void); extern NTSTATUS torture_raw_init(void); extern NTSTATUS torture_unix_init(void); extern NTSTATUS torture_winbind_init(void); -- cgit From 64d1b5c4e1efd734176c1ea6e5e564e626128b4f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 16 May 2009 18:10:39 -0400 Subject: Consolidate user create/delete paths in smbpasswd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch changes the way smbpasswd behaves when adding/deleting users. smbpasswd now calls pdb_create_user/pdb_delete_user, this means that if add/delete user scripts are configured then they are used to create or delete unix users as well. If the scripts are not defined the behavioris unchanged. This also allow to use smbpasswd -a/-x with ldapsam:editposix to allow automatic creation/deletion of users. Signed-off-by: Günther Deschner --- source3/passdb/passdb.c | 326 +++++++++++++++++++++++++--------------------- source3/utils/smbpasswd.c | 42 +++--- 2 files changed, 194 insertions(+), 174 deletions(-) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 6aab5e377c..9654e79d7a 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -627,7 +627,14 @@ bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid, } /************************************************************* - Change a password entry in the local smbpasswd file. + Change a password entry in the local passdb backend. + + Assumptions: + - always called as root + - ignores the account type except when adding a new account + - will create/delete the unix account if the relative + add/delete user script is configured + *************************************************************/ NTSTATUS local_password_change(const char *user_name, @@ -636,133 +643,135 @@ NTSTATUS local_password_change(const char *user_name, char **pp_err_str, char **pp_msg_str) { - struct samu *sam_pass=NULL; - uint32 other_acb; + TALLOC_CTX *tosctx; + struct samu *sam_pass; + uint32_t acb; + uint32_t rid; NTSTATUS result; + bool user_exists; + int ret; *pp_err_str = NULL; *pp_msg_str = NULL; - /* Get the smb passwd entry for this user */ - - if ( !(sam_pass = samu_new( NULL )) ) { + tosctx = talloc_tos(); + if (!tosctx) { return NT_STATUS_NO_MEMORY; } - become_root(); - if(!pdb_getsampwnam(sam_pass, user_name)) { - unbecome_root(); - TALLOC_FREE(sam_pass); - - if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) { - int tmp_debug = DEBUGLEVEL; - struct passwd *pwd; - - /* Might not exist in /etc/passwd. */ - - if (tmp_debug < 1) { - DEBUGLEVEL = 1; - } + sam_pass = samu_new(tosctx); + if (!sam_pass) { + result = NT_STATUS_NO_MEMORY; + goto done; + } - if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), user_name)) ) { - return NT_STATUS_NO_SUCH_USER; + /* Get the smb passwd entry for this user */ + user_exists = pdb_getsampwnam(sam_pass, user_name); + + /* Check delete first, we don't need to do anything else if we + * are going to delete the acocunt */ + if (user_exists && (local_flags & LOCAL_DELETE_USER)) { + + result = pdb_delete_user(tosctx, sam_pass); + if (!NT_STATUS_IS_OK(result)) { + ret = asprintf(pp_err_str, + "Failed to delete entry for user %s.\n", + user_name); + if (ret < 0) { + *pp_err_str = NULL; } - - /* create the struct samu and initialize the basic Unix properties */ - - if ( !(sam_pass = samu_new( NULL )) ) { - return NT_STATUS_NO_MEMORY; + result = NT_STATUS_UNSUCCESSFUL; + } else { + ret = asprintf(pp_msg_str, + "Deleted user %s.\n", + user_name); + if (ret < 0) { + *pp_msg_str = NULL; } + } + goto done; + } - result = samu_set_unix( sam_pass, pwd ); - - DEBUGLEVEL = tmp_debug; + if (user_exists && (local_flags & LOCAL_ADD_USER)) { + /* the entry already existed */ + local_flags &= ~LOCAL_ADD_USER; + } - TALLOC_FREE( pwd ); + if (!user_exists && !(local_flags & LOCAL_ADD_USER)) { + ret = asprintf(pp_err_str, + "Failed to find entry for user %s.\n", + user_name); + if (ret < 0) { + *pp_err_str = NULL; + } + result = NT_STATUS_NO_SUCH_USER; + goto done; + } - if (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PRIMARY_GROUP)) { - return result; - } + /* First thing add the new user if we are required to do so */ + if (local_flags & LOCAL_ADD_USER) { - if (!NT_STATUS_IS_OK(result)) { - if (asprintf(pp_err_str, "Failed to " "initialize account for user %s: %s\n", - user_name, nt_errstr(result)) < 0) { - *pp_err_str = NULL; - } - return result; - } + if (local_flags & LOCAL_TRUST_ACCOUNT) { + acb = ACB_WSTRUST; + } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) { + acb = ACB_DOMTRUST; } else { - if (asprintf(pp_err_str, "Failed to find entry for user %s.\n", user_name) < 0) { - *pp_err_str = NULL; - } - return NT_STATUS_NO_SUCH_USER; + acb = ACB_NORMAL; } - } else { - unbecome_root(); - /* the entry already existed */ - local_flags &= ~LOCAL_ADD_USER; - } - /* the 'other' acb bits not being changed here */ - other_acb = (pdb_get_acct_ctrl(sam_pass) & (~(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL))); - if (local_flags & LOCAL_TRUST_ACCOUNT) { - if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) { - if (asprintf(pp_err_str, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name) < 0) { + result = pdb_create_user(tosctx, user_name, acb, &rid); + if (!NT_STATUS_IS_OK(result)) { + ret = asprintf(pp_err_str, + "Failed to add entry for user %s.\n", + user_name); + if (ret < 0) { *pp_err_str = NULL; } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } - } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) { - if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) { - if (asprintf(pp_err_str, "Failed to set 'domain trust account' flags for user %s.\n", user_name) < 0) { - *pp_err_str = NULL; - } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; + + sam_pass = samu_new(tosctx); + if (!sam_pass) { + result = NT_STATUS_NO_MEMORY; + goto done; } - } else { - if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) { - if (asprintf(pp_err_str, "Failed to set 'normal account' flags for user %s.\n", user_name) < 0) { + + /* Now get back the smb passwd entry for this new user */ + user_exists = pdb_getsampwnam(sam_pass, user_name); + if (!user_exists) { + ret = asprintf(pp_err_str, + "Failed to add entry for user %s.\n", + user_name); + if (ret < 0) { *pp_err_str = NULL; } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } } + acb = pdb_get_acct_ctrl(sam_pass); + /* * We are root - just write the new password * and the valid last change time. */ - - if (local_flags & LOCAL_DISABLE_USER) { - if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) { - if (asprintf(pp_err_str, "Failed to set 'disabled' flag for user %s.\n", user_name) < 0) { - *pp_err_str = NULL; - } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; - } - } else if (local_flags & LOCAL_ENABLE_USER) { - if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) { - if (asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name) < 0) { + if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) { + acb |= ACB_PWNOTREQ; + if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { + ret = asprintf(pp_err_str, + "Failed to set 'no password required' " + "flag for user %s.\n", user_name); + if (ret < 0) { *pp_err_str = NULL; } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } } - if (local_flags & LOCAL_SET_NO_PASSWORD) { - if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) { - if (asprintf(pp_err_str, "Failed to set 'no password required' flag for user %s.\n", user_name) < 0) { - *pp_err_str = NULL; - } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; - } - } else if (local_flags & LOCAL_SET_PASSWORD) { + if (local_flags & LOCAL_SET_PASSWORD) { /* * If we're dealing with setting a completely empty user account * ie. One with a password of 'XXXX', but not set disabled (like @@ -772,83 +781,106 @@ NTSTATUS local_password_change(const char *user_name, * and the decision hasn't really been made to disable them (ie. * don't create them disabled). JRA. */ - if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) { - if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) { - if (asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name) < 0) { + if ((pdb_get_lanman_passwd(sam_pass) == NULL) && + (acb & ACB_DISABLED)) { + acb &= (~ACB_DISABLED); + if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { + ret = asprintf(pp_err_str, + "Failed to unset 'disabled' " + "flag for user %s.\n", + user_name); + if (ret < 0) { *pp_err_str = NULL; } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; - } - } - if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) { - if (asprintf(pp_err_str, "Failed to unset 'no password required' flag for user %s.\n", user_name) < 0) { - *pp_err_str = NULL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; } - if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) { - if (asprintf(pp_err_str, "Failed to set password for user %s.\n", user_name) < 0) { + acb &= (~ACB_PWNOTREQ); + if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { + ret = asprintf(pp_err_str, + "Failed to unset 'no password required'" + " flag for user %s.\n", user_name); + if (ret < 0) { *pp_err_str = NULL; } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } - } - if (local_flags & LOCAL_ADD_USER) { - if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass))) { - if (asprintf(pp_msg_str, "Added user %s.\n", user_name) < 0) { - *pp_msg_str = NULL; - } - TALLOC_FREE(sam_pass); - return NT_STATUS_OK; - } else { - if (asprintf(pp_err_str, "Failed to add entry for user %s.\n", user_name) < 0) { + if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) { + ret = asprintf(pp_err_str, + "Failed to set password for " + "user %s.\n", user_name); + if (ret < 0) { *pp_err_str = NULL; } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } - } else if (local_flags & LOCAL_DELETE_USER) { - if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass))) { - if (asprintf(pp_err_str, "Failed to delete entry for user %s.\n", user_name) < 0) { + } + + if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) { + acb |= ACB_DISABLED; + if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { + ret = asprintf(pp_err_str, + "Failed to set 'disabled' flag for " + "user %s.\n", user_name); + if (ret < 0) { *pp_err_str = NULL; } - TALLOC_FREE(sam_pass); - return NT_STATUS_UNSUCCESSFUL; - } - if (asprintf(pp_msg_str, "Deleted user %s.\n", user_name) < 0) { - *pp_msg_str = NULL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } - } else { - result = pdb_update_sam_account(sam_pass); - if(!NT_STATUS_IS_OK(result)) { - if (asprintf(pp_err_str, "Failed to modify entry for user %s.\n", user_name) < 0) { + } + + if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) { + acb &= (~ACB_DISABLED); + if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { + ret = asprintf(pp_err_str, + "Failed to unset 'disabled' flag for " + "user %s.\n", user_name); + if (ret < 0) { *pp_err_str = NULL; } - TALLOC_FREE(sam_pass); - return result; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } - if(local_flags & LOCAL_DISABLE_USER) { - if (asprintf(pp_msg_str, "Disabled user %s.\n", user_name) < 0) { - *pp_msg_str = NULL; - } - } else if (local_flags & LOCAL_ENABLE_USER) { - if (asprintf(pp_msg_str, "Enabled user %s.\n", user_name) < 0) { - *pp_msg_str = NULL; - } - } else if (local_flags & LOCAL_SET_NO_PASSWORD) { - if (asprintf(pp_msg_str, "User %s password set to none.\n", user_name) < 0) { - *pp_msg_str = NULL; - } + } + + /* now commit changes if any */ + result = pdb_update_sam_account(sam_pass); + if (!NT_STATUS_IS_OK(result)) { + ret = asprintf(pp_err_str, + "Failed to modify entry for user %s.\n", + user_name); + if (ret < 0) { + *pp_err_str = NULL; } + goto done; + } + + if (local_flags & LOCAL_ADD_USER) { + ret = asprintf(pp_msg_str, "Added user %s.\n", user_name); + } else if (local_flags & LOCAL_DISABLE_USER) { + ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name); + } else if (local_flags & LOCAL_ENABLE_USER) { + ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name); + } else if (local_flags & LOCAL_SET_NO_PASSWORD) { + ret = asprintf(pp_msg_str, + "User %s password set to none.\n", user_name); } + if (ret < 0) { + *pp_msg_str = NULL; + } + + result = NT_STATUS_OK; + +done: TALLOC_FREE(sam_pass); - return NT_STATUS_OK; + return result; } /********************************************************************** diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 8cca93f5de..c0b2cac18a 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -242,26 +242,29 @@ static NTSTATUS password_change(const char *remote_mach, char *username, char *msg_str = NULL; if (remote_mach != NULL) { - if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER| - LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) { + if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER| + LOCAL_DISABLE_USER|LOCAL_ENABLE_USER| + LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) { /* these things can't be done remotely yet */ + fprintf(stderr, "Invalid remote operation!\n"); return NT_STATUS_UNSUCCESSFUL; } - ret = remote_password_change(remote_mach, username, + ret = remote_password_change(remote_mach, username, old_passwd, new_pw, &err_str); - if (err_str != NULL) - fprintf(stderr, "%s", err_str); - SAFE_FREE(err_str); - return ret; + } else { + ret = local_password_change(username, local_flags, new_pw, + &err_str, &msg_str); } - ret = local_password_change(username, local_flags, new_pw, - &err_str, &msg_str); - - if(msg_str) + if (msg_str) { printf("%s", msg_str); - if(err_str) + } + if (err_str) { fprintf(stderr, "%s", err_str); + } + if (!NT_STATUS_IS_OK(ret) && !err_str) { + fprintf(stderr, "Failed to change password!\n"); + } SAFE_FREE(msg_str); SAFE_FREE(err_str); @@ -430,21 +433,8 @@ static int process_root(int local_flags) } if((local_flags & LOCAL_SET_PASSWORD) && (new_passwd == NULL)) { - struct passwd *passwd; - - if (remote_machine == NULL) { - passwd = getpwnam_alloc(NULL, user_name); - - if (!passwd) { - fprintf(stderr, "Cannot locate Unix account for " - "'%s'!\n", user_name); - exit(1); - } - TALLOC_FREE(passwd); - } new_passwd = prompt_for_new_password(stdin_passwd_get); - if(!new_passwd) { fprintf(stderr, "Unable to get new password.\n"); exit(1); @@ -455,7 +445,6 @@ static int process_root(int local_flags) if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name, old_passwd, new_passwd, local_flags))) { - fprintf(stderr,"Failed to modify password entry for user %s\n", user_name); result = 1; goto done; } @@ -550,7 +539,6 @@ static int process_nonroot(int local_flags) if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name, old_pw, new_pw, 0))) { - fprintf(stderr,"Failed to change password for %s\n", user_name); result = 1; goto done; } -- cgit From f48e39540c9767e9077e7534a6d410b4ce597c86 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 16 May 2009 20:36:28 -0400 Subject: Consolidate create/delete account paths in pdbedit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use common paths like for smbpasswd, so that all utilities behave the same way. As for smbpasswd this changes the behavior of pdbedit to create/delete unix users is the add/delete user scripts are provided, or ldapsam:editposix is configured. Signed-off-by: Günther Deschner --- source3/include/proto.h | 2 +- source3/param/loadparm.c | 5 + source3/utils/pdbedit.c | 576 ++++++++++++++++++++++++++--------------------- 3 files changed, 325 insertions(+), 258 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 7d297f6c32..d5e403fa85 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4312,7 +4312,7 @@ enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp); void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val); int lp_min_receive_file_size(void); char* lp_perfcount_module(void); - +void lp_set_passdb_backend(const char *backend); /* The following definitions come from param/util.c */ diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 57fdb6e044..7e4371bf0b 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -9775,3 +9775,8 @@ const char *lp_socket_address(void) } return Globals.szSocketAddress; } + +void lp_set_passdb_backend(const char *backend) +{ + string_set(&Globals.szPassdbBackend, backend); +} diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 328b2cb1f4..000f8c8d56 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -53,6 +53,7 @@ #define MASK_ALWAYS_GOOD 0x0000001F #define MASK_USER_GOOD 0x00405FE0 + /********************************************************* Add all currently available users to another db ********************************************************/ @@ -321,167 +322,187 @@ static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdst Get an Print User Info **********************************************************/ -static int print_user_info (struct pdb_methods *in, const char *username, bool verbosity, bool smbpwdstyle) +static int print_user_info(const char *username, + bool verbosity, bool smbpwdstyle) { - struct samu *sam_pwent=NULL; - bool ret; + struct samu *sam_pwent = NULL; + bool bret; + int ret; - if ( (sam_pwent = samu_new( NULL )) == NULL ) { + sam_pwent = samu_new(NULL); + if (!sam_pwent) { return -1; } - ret = NT_STATUS_IS_OK(in->getsampwnam (in, sam_pwent, username)); - - if (ret==False) { + bret = pdb_getsampwnam(sam_pwent, username); + if (!bret) { fprintf (stderr, "Username not found!\n"); TALLOC_FREE(sam_pwent); return -1; } - ret=print_sam_info (sam_pwent, verbosity, smbpwdstyle); + ret = print_sam_info(sam_pwent, verbosity, smbpwdstyle); + TALLOC_FREE(sam_pwent); - return ret; } - + /********************************************************* List Users **********************************************************/ -static int print_users_list (struct pdb_methods *in, bool verbosity, bool smbpwdstyle) +static int print_users_list(bool verbosity, bool smbpwdstyle) { struct pdb_search *u_search; struct samr_displayentry userentry; - - u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH); - if (u_search == NULL) { - DEBUG(0, ("pdb_search_init failed\n")); + struct samu *sam_pwent; + TALLOC_CTX *tosctx; + DOM_SID user_sid; + bool bret; + int ret; + + tosctx = talloc_tos(); + if (!tosctx) { + DEBUG(0, ("talloc failed\n")); return 1; } - if (!in->search_users(in, u_search, 0)) { - DEBUG(0, ("Could not start searching users\n")); - TALLOC_FREE(u_search); - return 1; + u_search = pdb_search_users(tosctx, 0); + if (!u_search) { + DEBUG(0, ("User Search failed!\n")); + ret = 1; + goto done; } while (u_search->next_entry(u_search, &userentry)) { - struct samu *sam_pwent; - DOM_SID user_sid; - NTSTATUS status; - sam_pwent = samu_new(talloc_tos()); + sam_pwent = samu_new(tosctx); if (sam_pwent == NULL) { DEBUG(0, ("talloc failed\n")); - break; + ret = 1; + goto done; } sid_compose(&user_sid, get_global_sam_sid(), userentry.rid); - status = in->getsampwsid(in, sam_pwent, &user_sid); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("getsampwsid failed: %s\n", - nt_errstr(status))); + bret = pdb_getsampwsid(sam_pwent, &user_sid); + if (!bret) { + DEBUG(2, ("getsampwsid failed\n")); TALLOC_FREE(sam_pwent); continue; } - if (verbosity) + if (verbosity) { printf ("---------------\n"); - print_sam_info (sam_pwent, verbosity, smbpwdstyle); + } + print_sam_info(sam_pwent, verbosity, smbpwdstyle); TALLOC_FREE(sam_pwent); } - TALLOC_FREE(u_search); - return 0; + ret = 0; + +done: + TALLOC_FREE(tosctx); + return ret; } /********************************************************* Fix a list of Users for uninitialised passwords **********************************************************/ -static int fix_users_list (struct pdb_methods *in) +static int fix_users_list(void) { struct pdb_search *u_search; struct samr_displayentry userentry; + struct samu *sam_pwent; + TALLOC_CTX *tosctx; + DOM_SID user_sid; + NTSTATUS status; + bool bret; + int ret; - u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH); - if (u_search == NULL) { - DEBUG(0, ("pdb_search_init failed\n")); + tosctx = talloc_tos(); + if (!tosctx) { + fprintf(stderr, "Out of memory!\n"); return 1; } - if (!in->search_users(in, u_search, 0)) { - DEBUG(0, ("Could not start searching users\n")); - TALLOC_FREE(u_search); - return 1; + u_search = pdb_search_users(tosctx, 0); + if (!u_search) { + fprintf(stderr, "User Search failed!\n"); + ret = 1; + goto done; } while (u_search->next_entry(u_search, &userentry)) { - struct samu *sam_pwent; - DOM_SID user_sid; - NTSTATUS status; - sam_pwent = samu_new(talloc_tos()); + sam_pwent = samu_new(tosctx); if (sam_pwent == NULL) { - DEBUG(0, ("talloc failed\n")); - break; + fprintf(stderr, "Out of memory!\n"); + ret = 1; + goto done; } sid_compose(&user_sid, get_global_sam_sid(), userentry.rid); - status = in->getsampwsid(in, sam_pwent, &user_sid); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("getsampwsid failed: %s\n", - nt_errstr(status))); + bret = pdb_getsampwsid(sam_pwent, &user_sid); + if (!bret) { + DEBUG(2, ("getsampwsid failed\n")); TALLOC_FREE(sam_pwent); continue; } - if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) { + status = pdb_update_sam_account(sam_pwent); + if (!NT_STATUS_IS_OK(status)) { printf("Update of user %s failed!\n", pdb_get_username(sam_pwent)); } TALLOC_FREE(sam_pwent); } - TALLOC_FREE(u_search); - return 0; + + ret = 0; + +done: + TALLOC_FREE(tosctx); + return ret; } /********************************************************* Set User Info **********************************************************/ -static int set_user_info (struct pdb_methods *in, const char *username, - const char *fullname, const char *homedir, - const char *acct_desc, - const char *drive, const char *script, - const char *profile, const char *account_control, - const char *user_sid, const char *user_domain, - const bool badpw, const bool hours) +static int set_user_info(const char *username, const char *fullname, + const char *homedir, const char *acct_desc, + const char *drive, const char *script, + const char *profile, const char *account_control, + const char *user_sid, const char *user_domain, + const bool badpw, const bool hours) { bool updated_autolock = False, updated_badpw = False; - struct samu *sam_pwent=NULL; + struct samu *sam_pwent; + uint8_t hours_array[MAX_HOURS_LEN]; + uint32_t hours_len; + uint32_t acb_flags; + uint32_t not_settable; + uint32_t new_flags; + DOM_SID u_sid; + int u_rid; bool ret; - - if ( (sam_pwent = samu_new( NULL )) == NULL ) { + + sam_pwent = samu_new(NULL); + if (!sam_pwent) { return 1; } - - ret = NT_STATUS_IS_OK(in->getsampwnam (in, sam_pwent, username)); - if (ret==False) { + + ret = pdb_getsampwnam(sam_pwent, username); + if (!ret) { fprintf (stderr, "Username not found!\n"); TALLOC_FREE(sam_pwent); return -1; } if (hours) { - uint8 hours_array[MAX_HOURS_LEN]; - uint32 hours_len; - hours_len = pdb_get_hours_len(sam_pwent); memset(hours_array, 0xff, hours_len); - + pdb_set_hours(sam_pwent, hours_array, PDB_CHANGED); } @@ -509,27 +530,28 @@ static int set_user_info (struct pdb_methods *in, const char *username, pdb_set_domain(sam_pwent, user_domain, PDB_CHANGED); if (account_control) { - uint32 not_settable = ~(ACB_DISABLED|ACB_HOMDIRREQ|ACB_PWNOTREQ| - ACB_PWNOEXP|ACB_AUTOLOCK); + not_settable = ~(ACB_DISABLED | ACB_HOMDIRREQ | + ACB_PWNOTREQ | ACB_PWNOEXP | ACB_AUTOLOCK); - uint32 newflag = pdb_decode_acct_ctrl(account_control); + new_flags = pdb_decode_acct_ctrl(account_control); - if (newflag & not_settable) { + if (new_flags & not_settable) { fprintf(stderr, "Can only set [NDHLX] flags\n"); TALLOC_FREE(sam_pwent); return -1; } + acb_flags = pdb_get_acct_ctrl(sam_pwent); + pdb_set_acct_ctrl(sam_pwent, - (pdb_get_acct_ctrl(sam_pwent) & not_settable) | newflag, + (acb_flags & not_settable) | new_flags, PDB_CHANGED); } if (user_sid) { - DOM_SID u_sid; if (!string_to_sid(&u_sid, user_sid)) { - /* not a complete sid, may be a RID, try building a SID */ - int u_rid; - + /* not a complete sid, may be a RID, + * try building a SID */ + if (sscanf(user_sid, "%d", &u_rid) != 1) { fprintf(stderr, "Error passed string is not a complete user SID or RID!\n"); return -1; @@ -537,7 +559,7 @@ static int set_user_info (struct pdb_methods *in, const char *username, sid_copy(&u_sid, get_global_sam_sid()); sid_append_rid(&u_sid, u_rid); } - pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED); + pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED); } if (badpw) { @@ -545,9 +567,9 @@ static int set_user_info (struct pdb_methods *in, const char *username, pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED); } - if (NT_STATUS_IS_OK(in->update_sam_account (in, sam_pwent))) - print_user_info (in, username, True, False); - else { + if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) { + print_user_info(username, True, False); + } else { fprintf (stderr, "Unable to modify entry!\n"); TALLOC_FREE(sam_pwent); return -1; @@ -559,177 +581,201 @@ static int set_user_info (struct pdb_methods *in, const char *username, /********************************************************* Add New User **********************************************************/ -static int new_user (struct pdb_methods *in, const char *username, - const char *fullname, const char *homedir, - const char *drive, const char *script, - const char *profile, char *user_sid, bool stdin_get) +static int new_user(const char *username, const char *fullname, + const char *homedir, const char *drive, + const char *script, const char *profile, + char *user_sid, bool stdin_get) { + char *pwd1 = NULL, *pwd2 = NULL; + char *err = NULL, *msg = NULL; struct samu *sam_pwent; - char *password1, *password2; - int rc_pwd_cmp; - struct passwd *pwd; - - get_global_sam_sid(); - - if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), username )) ) { - DEBUG(0,("Cannot locate Unix account for %s\n", username)); + TALLOC_CTX *tosctx; + NTSTATUS status; + DOM_SID u_sid; + int u_rid; + int flags; + int ret; + + tosctx = talloc_tos(); + if (!tosctx) { + fprintf(stderr, "Out of memory!\n"); return -1; } - if ( (sam_pwent = samu_new( NULL )) == NULL ) { - DEBUG(0, ("Memory allocation failure!\n")); - return -1; - } - if (!NT_STATUS_IS_OK(samu_alloc_rid_unix(sam_pwent, pwd ))) { - TALLOC_FREE( sam_pwent ); - TALLOC_FREE( pwd ); - DEBUG(0, ("could not create account to add new user %s\n", username)); - return -1; + if (user_sid) { + if (!string_to_sid(&u_sid, user_sid)) { + /* not a complete sid, may be a RID, + * try building a SID */ + + if (sscanf(user_sid, "%d", &u_rid) != 1) { + fprintf(stderr, "Error passed string is not a complete user SID or RID!\n"); + ret = -1; + goto done; + } + sid_copy(&u_sid, get_global_sam_sid()); + sid_append_rid(&u_sid, u_rid); + } } - password1 = get_pass( "new password:", stdin_get); - password2 = get_pass( "retype new password:", stdin_get); - if ((rc_pwd_cmp = strcmp (password1, password2))) { + pwd1 = get_pass( "new password:", stdin_get); + pwd2 = get_pass( "retype new password:", stdin_get); + ret = strcmp(pwd1, pwd2); + if (ret != 0) { fprintf (stderr, "Passwords do not match!\n"); - TALLOC_FREE(sam_pwent); - } else { - pdb_set_plaintext_passwd(sam_pwent, password1); + goto done; } - memset(password1, 0, strlen(password1)); - SAFE_FREE(password1); - memset(password2, 0, strlen(password2)); - SAFE_FREE(password2); + flags = LOCAL_ADD_USER | LOCAL_SET_PASSWORD; - /* pwds do _not_ match? */ - if (rc_pwd_cmp) - return -1; + status = local_password_change(username, flags, pwd1, &err, &msg); + if (!NT_STATUS_IS_OK(status)) { + if (err) fprintf(stderr, err); + ret = -1; + goto done; + } + + sam_pwent = samu_new(tosctx); + if (!sam_pwent) { + fprintf(stderr, "Out of memory!\n"); + ret = -1; + goto done; + } + + if (!pdb_getsampwnam(sam_pwent, username)) { + fprintf(stderr, "User %s not found!\n", username); + ret = -1; + goto done; + } if (fullname) pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED); if (homedir) - pdb_set_homedir (sam_pwent, homedir, PDB_CHANGED); + pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED); if (drive) - pdb_set_dir_drive (sam_pwent, drive, PDB_CHANGED); + pdb_set_dir_drive(sam_pwent, drive, PDB_CHANGED); if (script) pdb_set_logon_script(sam_pwent, script, PDB_CHANGED); if (profile) - pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED); - if (user_sid) { - DOM_SID u_sid; - if (!string_to_sid(&u_sid, user_sid)) { - /* not a complete sid, may be a RID, try building a SID */ - int u_rid; - - if (sscanf(user_sid, "%d", &u_rid) != 1) { - fprintf(stderr, "Error passed string is not a complete user SID or RID!\n"); - TALLOC_FREE(sam_pwent); - return -1; - } - sid_copy(&u_sid, get_global_sam_sid()); - sid_append_rid(&u_sid, u_rid); - } - pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED); + pdb_set_profile_path(sam_pwent, profile, PDB_CHANGED); + if (user_sid) + pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED); + + status = pdb_update_sam_account(sam_pwent); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, + "Failed to modify entry for user %s.!\n", + username); + ret = -1; + goto done; } - - pdb_set_acct_ctrl (sam_pwent, ACB_NORMAL, PDB_CHANGED); - - if (NT_STATUS_IS_OK(in->add_sam_account (in, sam_pwent))) { - print_user_info (in, username, True, False); - } else { - fprintf (stderr, "Unable to add user! (does it already exist?)\n"); - TALLOC_FREE(sam_pwent); - return -1; - } - TALLOC_FREE(sam_pwent); - return 0; + + print_user_info(username, True, False); + ret = 0; + +done: + if (pwd1) memset(pwd1, 0, strlen(pwd1)); + if (pwd2) memset(pwd2, 0, strlen(pwd2)); + SAFE_FREE(pwd1); + SAFE_FREE(pwd2); + SAFE_FREE(err); + SAFE_FREE(msg); + TALLOC_FREE(tosctx); + return ret; } /********************************************************* Add New Machine **********************************************************/ -static int new_machine (struct pdb_methods *in, const char *machine_in) +static int new_machine(const char *machinename) { - struct samu *sam_pwent=NULL; - fstring machinename; - fstring machineaccount; - struct passwd *pwd = NULL; - - get_global_sam_sid(); - - if (strlen(machine_in) == 0) { + char *err = NULL, *msg = NULL; + TALLOC_CTX *tosctx; + NTSTATUS status; + char *compatpwd; + char *name; + int flags; + int len; + int ret; + + len = strlen(machinename); + if (len == 0) { fprintf(stderr, "No machine name given\n"); return -1; } - fstrcpy(machinename, machine_in); - machinename[15]= '\0'; - - if (machinename[strlen (machinename) -1] == '$') - machinename[strlen (machinename) -1] = '\0'; - - strlower_m(machinename); - - fstrcpy(machineaccount, machinename); - fstrcat(machineaccount, "$"); - - if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), machineaccount )) ) { - DEBUG(0,("Cannot locate Unix account for %s\n", machineaccount)); + tosctx = talloc_tos(); + if (!tosctx) { + fprintf(stderr, "Out of memory!\n"); return -1; } - if ( (sam_pwent = samu_new( NULL )) == NULL ) { - fprintf(stderr, "Memory allocation error!\n"); - TALLOC_FREE(pwd); + compatpwd = talloc_strdup(tosctx, machinename); + if (!compatpwd) { + fprintf(stderr, "Out of memory!\n"); return -1; } - if ( !NT_STATUS_IS_OK(samu_alloc_rid_unix(sam_pwent, pwd )) ) { - fprintf(stderr, "Could not init sam from pw\n"); - TALLOC_FREE(pwd); + if (machinename[len-1] == '$') { + name = talloc_strdup(tosctx, machinename); + compatpwd[len-1] = '\0'; + } else { + name = talloc_asprintf(tosctx, "%s$", machinename); + } + if (!name) { + fprintf(stderr, "Out of memory!\n"); return -1; } - TALLOC_FREE(pwd); + strlower_m(name); + + flags = LOCAL_ADD_USER | LOCAL_TRUST_ACCOUNT | LOCAL_SET_PASSWORD; + + status = local_password_change(name, flags, compatpwd, &err, &msg); - pdb_set_plaintext_passwd (sam_pwent, machinename); - pdb_set_username (sam_pwent, machineaccount, PDB_CHANGED); - pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST, PDB_CHANGED); - - if (NT_STATUS_IS_OK(in->add_sam_account (in, sam_pwent))) { - print_user_info (in, machineaccount, True, False); + if (NT_STATUS_IS_OK(status)) { + print_user_info(name, True, False); + ret = 0; } else { - fprintf (stderr, "Unable to add machine! (does it already exist?)\n"); - TALLOC_FREE(sam_pwent); - return -1; + if (err) fprintf(stderr, err); + ret = -1; } - TALLOC_FREE(sam_pwent); - return 0; + + TALLOC_FREE(tosctx); + SAFE_FREE(err); + SAFE_FREE(msg); + return ret; } /********************************************************* Delete user entry **********************************************************/ -static int delete_user_entry (struct pdb_methods *in, const char *username) +static int delete_user_entry(const char *username) { - struct samu *samaccount = NULL; + struct samu *samaccount; - if ( (samaccount = samu_new( NULL )) == NULL ) { + samaccount = samu_new(NULL); + if (!samaccount) { + fprintf(stderr, "Out of memory!\n"); return -1; } - if (!NT_STATUS_IS_OK(in->getsampwnam(in, samaccount, username))) { - fprintf (stderr, "user %s does not exist in the passdb\n", username); + if (!pdb_getsampwnam(samaccount, username)) { + fprintf (stderr, + "user %s does not exist in the passdb\n", username); + TALLOC_FREE(samaccount); return -1; } - if (!NT_STATUS_IS_OK(in->delete_sam_account (in, samaccount))) { + if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) { fprintf (stderr, "Unable to delete user %s\n", username); + TALLOC_FREE(samaccount); return -1; } + + TALLOC_FREE(samaccount); return 0; } @@ -737,35 +783,42 @@ static int delete_user_entry (struct pdb_methods *in, const char *username) Delete machine entry **********************************************************/ -static int delete_machine_entry (struct pdb_methods *in, const char *machinename) +static int delete_machine_entry(const char *machinename) { - fstring name; struct samu *samaccount = NULL; + const char *name; if (strlen(machinename) == 0) { fprintf(stderr, "No machine name given\n"); return -1; } - - fstrcpy(name, machinename); - name[15] = '\0'; - if (name[strlen(name)-1] != '$') - fstrcat (name, "$"); - if ( (samaccount = samu_new( NULL )) == NULL ) { + samaccount = samu_new(NULL); + if (!samaccount) { + fprintf(stderr, "Out of memory!\n"); return -1; } - if (!NT_STATUS_IS_OK(in->getsampwnam(in, samaccount, name))) { - fprintf (stderr, "machine %s does not exist in the passdb\n", name); + if (machinename[strlen(machinename)-1] != '$') { + name = talloc_asprintf(samaccount, "%s$", machinename); + } else { + name = machinename; + } + + if (!pdb_getsampwnam(samaccount, name)) { + fprintf (stderr, + "machine %s does not exist in the passdb\n", name); return -1; + TALLOC_FREE(samaccount); } - if (!NT_STATUS_IS_OK(in->delete_sam_account (in, samaccount))) { + if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) { fprintf (stderr, "Unable to delete machine %s\n", name); + TALLOC_FREE(samaccount); return -1; } + TALLOC_FREE(samaccount); return 0; } @@ -789,7 +842,7 @@ int main (int argc, char **argv) static const char *user_name = NULL; static char *home_dir = NULL; static char *home_drive = NULL; - static char *backend = NULL; + static const char *backend = NULL; static char *backend_in = NULL; static char *backend_out = NULL; static int transfer_groups = False; @@ -808,8 +861,9 @@ int main (int argc, char **argv) static int hours_reset = False; static char *pwd_time_format = NULL; static int pw_from_stdin = False; - struct pdb_methods *bin, *bout, *bdef; + struct pdb_methods *bin, *bout; TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; poptContext pc; struct poptOption long_options[] = { POPT_AUTOHELP @@ -846,16 +900,16 @@ int main (int argc, char **argv) POPT_COMMON_SAMBA POPT_TABLEEND }; - - bin = bout = bdef = NULL; + + bin = bout = NULL; load_case_tables(); setup_logging("pdbedit", True); - + pc = poptGetContext(NULL, argc, (const char **) argv, long_options, POPT_CONTEXT_KEEP_FIRST); - + while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case 'C': @@ -874,9 +928,6 @@ int main (int argc, char **argv) exit(1); } - if(!initialize_password_db(False, NULL)) - exit(1); - if (!init_names()) exit(1); @@ -906,22 +957,24 @@ int main (int argc, char **argv) (hours_reset ? BIT_LOGONHOURS : 0); if (setparms & BIT_BACKEND) { - if (!NT_STATUS_IS_OK(make_pdb_method_name( &bdef, backend ))) { - fprintf(stderr, "Can't initialize passdb backend.\n"); - return 1; - } + /* HACK: set the global passdb backend by overwriting globals. + * This way we can use regular pdb functions for default + * operations that do not involve passdb migrations */ + lp_set_passdb_backend(backend); } else { - if (!NT_STATUS_IS_OK(make_pdb_method_name(&bdef, lp_passdb_backend()))) { - fprintf(stderr, "Can't initialize passdb backend.\n"); - return 1; - } + backend = lp_passdb_backend(); + } + + if (!initialize_password_db(False, NULL)) { + fprintf(stderr, "Can't initialize passdb backend.\n"); + exit(1); } - + /* the lowest bit options are always accepted */ checkparms = setparms & ~MASK_ALWAYS_GOOD; if (checkparms & BIT_FIX_INIT) { - return fix_users_list(bdef); + return fix_users_list(); } /* account policy operations */ @@ -973,45 +1026,49 @@ int main (int argc, char **argv) /* import and export operations */ - if ( ((checkparms & BIT_IMPORT) - || (checkparms & BIT_EXPORT)) - && !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER)) ) - { - NTSTATUS status; - - bin = bout = bdef; + if (((checkparms & BIT_IMPORT) || + (checkparms & BIT_EXPORT)) && + !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER))) { if (backend_in) { status = make_pdb_method_name(&bin, backend_in); + } else { + status = make_pdb_method_name(&bin, backend); + } - if ( !NT_STATUS_IS_OK(status) ) { - fprintf(stderr, "Unable to initialize %s.\n", backend_in); - return 1; - } + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "Unable to initialize %s.\n", + backend_in ? backend_in : backend); + return 1; } if (backend_out) { status = make_pdb_method_name(&bout, backend_out); + } else { + status = make_pdb_method_name(&bout, backend); + } - if ( !NT_STATUS_IS_OK(status) ) { - fprintf(stderr, "Unable to initialize %s.\n", backend_out); - return 1; - } + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, "Unable to initialize %s.\n", + backend_out ? backend_out : backend); + return 1; } if (transfer_account_policies) { - if (!(checkparms & BIT_USER)) + if (!(checkparms & BIT_USER)) { return export_account_policies(bin, bout); + } } else if (transfer_groups) { - if (!(checkparms & BIT_USER)) + if (!(checkparms & BIT_USER)) { return export_groups(bin, bout); + } } else { - return export_database(bin, bout, - (checkparms & BIT_USER) ? user_name : NULL ); + return export_database(bin, bout, + (checkparms & BIT_USER) ? user_name : NULL); } } @@ -1020,7 +1077,7 @@ int main (int argc, char **argv) if ((checkparms & BIT_USER) && !(checkparms & ~BIT_USER)) { checkparms += BIT_LIST; } - + /* modify flag is optional to maintain backwards compatibility */ /* fake up BIT_MODIFY if BIT_USER and at least one of MASK_USER_GOOD is defined */ if (!((checkparms & ~MASK_USER_GOOD) & ~BIT_USER) && (checkparms & MASK_USER_GOOD)) { @@ -1030,13 +1087,13 @@ int main (int argc, char **argv) /* list users operations */ if (checkparms & BIT_LIST) { if (!(checkparms & ~BIT_LIST)) { - return print_users_list (bdef, verbose, spstyle); + return print_users_list(verbose, spstyle); } if (!(checkparms & ~(BIT_USER + BIT_LIST))) { - return print_user_info (bdef, user_name, verbose, spstyle); + return print_user_info(user_name, verbose, spstyle); } } - + /* mask out users options */ checkparms &= ~MASK_USER_GOOD; @@ -1051,7 +1108,7 @@ int main (int argc, char **argv) checkparms |= BIT_MODIFY; checkparms &= ~BIT_LOGONHOURS; } - + /* account operation */ if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) { /* check use of -u option */ @@ -1063,27 +1120,32 @@ int main (int argc, char **argv) /* account creation operations */ if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) { if (checkparms & BIT_MACHINE) { - return new_machine (bdef, user_name); + return new_machine(user_name); } else { - return new_user (bdef, user_name, full_name, home_dir, - home_drive, logon_script, profile_path, user_sid, pw_from_stdin); + return new_user(user_name, full_name, + home_dir, home_drive, + logon_script, profile_path, + user_sid, pw_from_stdin); } } /* account deletion operations */ if (!(checkparms & ~(BIT_DELETE + BIT_USER + BIT_MACHINE))) { if (checkparms & BIT_MACHINE) { - return delete_machine_entry (bdef, user_name); + return delete_machine_entry(user_name); } else { - return delete_user_entry (bdef, user_name); + return delete_user_entry(user_name); } } /* account modification operations */ if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) { - return set_user_info (bdef, user_name, full_name, home_dir, - acct_desc, home_drive, logon_script, profile_path, account_control, - user_sid, user_domain, badpw_reset, hours_reset); + return set_user_info(user_name, full_name, + home_dir, acct_desc, + home_drive, logon_script, + profile_path, account_control, + user_sid, user_domain, + badpw_reset, hours_reset); } } -- cgit From 10eec5ebc01e166ac1759748a5a9bffff77bf44f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 18:08:02 +0200 Subject: s3-passdb: fix uninitialized variable in local_password_change(). Guenther --- 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 9654e79d7a..51190e0bc2 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -649,7 +649,7 @@ NTSTATUS local_password_change(const char *user_name, uint32_t rid; NTSTATUS result; bool user_exists; - int ret; + int ret = -1; *pp_err_str = NULL; *pp_msg_str = NULL; -- cgit From 3d07a929e6e0606d841694befdd236782a2036b5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 16:39:04 +0200 Subject: s4-smbtorture: add NETAPI-USER test. Guenther --- source4/torture/libnetapi/config.mk | 3 +- source4/torture/libnetapi/libnetapi.c | 1 + source4/torture/libnetapi/libnetapi_user.c | 476 +++++++++++++++++++++++++++++ 3 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 source4/torture/libnetapi/libnetapi_user.c diff --git a/source4/torture/libnetapi/config.mk b/source4/torture/libnetapi/config.mk index ea4166c944..0a4085f6d6 100644 --- a/source4/torture/libnetapi/config.mk +++ b/source4/torture/libnetapi/config.mk @@ -10,6 +10,7 @@ PRIVATE_DEPENDENCIES = \ # End SUBSYSTEM TORTURE_LIBNETAPI ################################# -TORTURE_LIBNETAPI_OBJ_FILES = $(addprefix $(torturesrcdir)/libnetapi/, libnetapi.o) +TORTURE_LIBNETAPI_OBJ_FILES = $(addprefix $(torturesrcdir)/libnetapi/, libnetapi.o \ + libnetapi_user.o) $(eval $(call proto_header_template,$(torturesrcdir)/libnetapi/proto.h,$(TORTURE_LIBNETAPI_OBJ_FILES:.o=.c))) diff --git a/source4/torture/libnetapi/libnetapi.c b/source4/torture/libnetapi/libnetapi.c index 761a67ff22..a023ee135f 100644 --- a/source4/torture/libnetapi/libnetapi.c +++ b/source4/torture/libnetapi/libnetapi.c @@ -68,6 +68,7 @@ NTSTATUS torture_libnetapi_init(void) suite = torture_suite_create(talloc_autofree_context(), "NETAPI"); + torture_suite_add_simple_test(suite, "USER", torture_libnetapi_user); torture_suite_add_simple_test(suite, "INITIALIZE", torture_libnetapi_initialize); suite->description = talloc_strdup(suite, "libnetapi convenience interface tests"); diff --git a/source4/torture/libnetapi/libnetapi_user.c b/source4/torture/libnetapi/libnetapi_user.c new file mode 100644 index 0000000000..c6343301e3 --- /dev/null +++ b/source4/torture/libnetapi/libnetapi_user.c @@ -0,0 +1,476 @@ +/* + Unix SMB/CIFS implementation. + SMB torture tester + Copyright (C) Guenther Deschner 2009 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "torture/smbtorture.h" +#include +#include "torture/libnetapi/proto.h" + +#define TORTURE_TEST_USER "testuser" + +#define NETAPI_STATUS(tctx, x,y,fn) \ + torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d)\n", \ + __LINE__, fn, libnetapi_get_error_string(x,y), y); + +static NET_API_STATUS test_netuserenum(struct torture_context *tctx, + const char *hostname, + uint32_t level, + const char *username) +{ + NET_API_STATUS status; + uint32_t entries_read = 0; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + const char *current_name = NULL; + int found_user = 0; + uint8_t *buffer = NULL; + int i; + + struct USER_INFO_0 *info0 = NULL; + struct USER_INFO_1 *info1 = NULL; + struct USER_INFO_2 *info2 = NULL; + struct USER_INFO_3 *info3 = NULL; + struct USER_INFO_4 *info4 = NULL; + struct USER_INFO_10 *info10 = NULL; + struct USER_INFO_11 *info11 = NULL; + struct USER_INFO_20 *info20 = NULL; + struct USER_INFO_23 *info23 = NULL; + + torture_comment(tctx, "testing NetUserEnum level %d\n", level); + + do { + status = NetUserEnum(hostname, + level, + FILTER_NORMAL_ACCOUNT, + &buffer, + (uint32_t)-1, + &entries_read, + &total_entries, + &resume_handle); + if (status == 0 || status == ERROR_MORE_DATA) { + switch (level) { + case 0: + info0 = (struct USER_INFO_0 *)buffer; + break; + case 1: + info1 = (struct USER_INFO_1 *)buffer; + break; + case 2: + info2 = (struct USER_INFO_2 *)buffer; + break; + case 3: + info3 = (struct USER_INFO_3 *)buffer; + break; + case 4: + info4 = (struct USER_INFO_4 *)buffer; + break; + case 10: + info10 = (struct USER_INFO_10 *)buffer; + break; + case 11: + info11 = (struct USER_INFO_11 *)buffer; + break; + case 20: + info20 = (struct USER_INFO_20 *)buffer; + break; + case 23: + info23 = (struct USER_INFO_23 *)buffer; + break; + default: + return -1; + } + + for (i=0; iusri0_name; + break; + case 1: + current_name = info1->usri1_name; + break; + case 2: + current_name = info2->usri2_name; + break; + case 3: + current_name = info3->usri3_name; + break; + case 4: + current_name = info4->usri4_name; + break; + case 10: + current_name = info10->usri10_name; + break; + case 11: + current_name = info11->usri11_name; + break; + case 20: + current_name = info20->usri20_name; + break; + case 23: + current_name = info23->usri23_name; + break; + default: + return -1; + } + + if (strcasecmp(current_name, username) == 0) { + found_user = 1; + } + + switch (level) { + case 0: + info0++; + break; + case 1: + info1++; + break; + case 2: + info2++; + break; + case 3: + info3++; + break; + case 4: + info4++; + break; + case 10: + info10++; + break; + case 11: + info11++; + break; + case 20: + info20++; + break; + case 23: + info23++; + break; + default: + break; + } + } + NetApiBufferFree(buffer); + } + } while (status == ERROR_MORE_DATA); + + if (status) { + return status; + } + + if (!found_user) { + torture_comment(tctx, "failed to get user\n"); + return -1; + } + + return 0; +} + +NET_API_STATUS test_netuseradd(struct torture_context *tctx, + const char *hostname, + const char *username) +{ + struct USER_INFO_1 u1; + uint32_t parm_err = 0; + + ZERO_STRUCT(u1); + + torture_comment(tctx, "testing NetUserAdd\n"); + + u1.usri1_name = username; + u1.usri1_password = "W297!832jD8J"; + u1.usri1_password_age = 0; + u1.usri1_priv = 0; + u1.usri1_home_dir = NULL; + u1.usri1_comment = "User created using Samba NetApi Example code"; + u1.usri1_flags = 0; + u1.usri1_script_path = NULL; + + return NetUserAdd(hostname, 1, (uint8_t *)&u1, &parm_err); +} + +static NET_API_STATUS test_netusermodals(struct torture_context *tctx, + struct libnetapi_ctx *ctx, + const char *hostname) +{ + NET_API_STATUS status; + struct USER_MODALS_INFO_0 *u0 = NULL; + struct USER_MODALS_INFO_0 *_u0 = NULL; + uint8_t *buffer = NULL; + uint32_t parm_err = 0; + uint32_t levels[] = { 0, 1, 2, 3 }; + int i = 0; + + for (i=0; igrui0_name; + break; + case 1: + current_name = i1->grui1_name; + break; + default: + return -1; + } + + if (groupname && strcasecmp(current_name, groupname) == 0) { + found_group = 1; + } + + switch (level) { + case 0: + i0++; + break; + case 1: + i1++; + break; + default: + break; + } + } + NetApiBufferFree(buffer); + } + } while (status == ERROR_MORE_DATA); + + if (status) { + return status; + } + + if (groupname && !found_group) { + torture_comment(tctx, "failed to get membership\n"); + return -1; + } + + return 0; +} + +bool torture_libnetapi_user(struct torture_context *tctx) +{ + NET_API_STATUS status = 0; + const char *username, *username2; + uint8_t *buffer = NULL; + uint32_t levels[] = { 0, 1, 2, 3, 4, 10, 11, 20, 23 }; + uint32_t enum_levels[] = { 0, 1, 2, 3, 4, 10, 11, 20, 23 }; + uint32_t getgr_levels[] = { 0, 1 }; + int i; + + struct USER_INFO_1007 u1007; + uint32_t parm_err = 0; + + const char *hostname = torture_setting_string(tctx, "host", NULL); + struct libnetapi_ctx *ctx; + + torture_assert(tctx, torture_libnetapi_init_context(tctx, &ctx), + "failed to initialize libnetapi"); + + torture_comment(tctx, "NetUser tests\n"); + + username = "torture_test_user"; + username2 = "torture_test_user2"; + + /* cleanup */ + NetUserDel(hostname, username); + NetUserDel(hostname, username2); + + /* add a user */ + + status = test_netuseradd(tctx, hostname, username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserAdd"); + goto out; + } + + /* enum the new user */ + + for (i=0; i Date: Fri, 29 May 2009 16:49:29 +0200 Subject: s4-smbtorture: add NETAPI-GROUP test. Guenther --- source4/torture/libnetapi/config.mk | 3 +- source4/torture/libnetapi/libnetapi.c | 1 + source4/torture/libnetapi/libnetapi_group.c | 520 ++++++++++++++++++++++++++++ 3 files changed, 523 insertions(+), 1 deletion(-) create mode 100644 source4/torture/libnetapi/libnetapi_group.c diff --git a/source4/torture/libnetapi/config.mk b/source4/torture/libnetapi/config.mk index 0a4085f6d6..2ac506e1b2 100644 --- a/source4/torture/libnetapi/config.mk +++ b/source4/torture/libnetapi/config.mk @@ -11,6 +11,7 @@ PRIVATE_DEPENDENCIES = \ ################################# TORTURE_LIBNETAPI_OBJ_FILES = $(addprefix $(torturesrcdir)/libnetapi/, libnetapi.o \ - libnetapi_user.o) + libnetapi_user.o \ + libnetapi_group.o) $(eval $(call proto_header_template,$(torturesrcdir)/libnetapi/proto.h,$(TORTURE_LIBNETAPI_OBJ_FILES:.o=.c))) diff --git a/source4/torture/libnetapi/libnetapi.c b/source4/torture/libnetapi/libnetapi.c index a023ee135f..c3a27eba0c 100644 --- a/source4/torture/libnetapi/libnetapi.c +++ b/source4/torture/libnetapi/libnetapi.c @@ -68,6 +68,7 @@ NTSTATUS torture_libnetapi_init(void) suite = torture_suite_create(talloc_autofree_context(), "NETAPI"); + torture_suite_add_simple_test(suite, "GROUP", torture_libnetapi_group); torture_suite_add_simple_test(suite, "USER", torture_libnetapi_user); torture_suite_add_simple_test(suite, "INITIALIZE", torture_libnetapi_initialize); diff --git a/source4/torture/libnetapi/libnetapi_group.c b/source4/torture/libnetapi/libnetapi_group.c new file mode 100644 index 0000000000..e8e5ad931a --- /dev/null +++ b/source4/torture/libnetapi/libnetapi_group.c @@ -0,0 +1,520 @@ +/* + Unix SMB/CIFS implementation. + SMB torture tester + Copyright (C) Guenther Deschner 2009 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "torture/smbtorture.h" +#include +#include "torture/libnetapi/proto.h" + +#define TORTURE_TEST_USER "testuser" + +#define NETAPI_STATUS(tctx, x,y,fn) \ + torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d)\n", \ + __LINE__, fn, libnetapi_get_error_string(x,y), y); + +#define NETAPI_STATUS_MSG(tctx, x,y,fn,z) \ + torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d), %s\n", \ + __LINE__, fn, libnetapi_get_error_string(x,y), y, z); + +static NET_API_STATUS test_netgroupenum(struct torture_context *tctx, + const char *hostname, + uint32_t level, + const char *groupname) +{ + NET_API_STATUS status; + uint32_t entries_read = 0; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + int found_group = 0; + const char *current_name = NULL; + uint8_t *buffer = NULL; + int i; + + struct GROUP_INFO_0 *info0 = NULL; + struct GROUP_INFO_1 *info1 = NULL; + struct GROUP_INFO_2 *info2 = NULL; + struct GROUP_INFO_3 *info3 = NULL; + + torture_comment(tctx, "testing NetGroupEnum level %d\n", level); + + do { + status = NetGroupEnum(hostname, + level, + &buffer, + (uint32_t)-1, + &entries_read, + &total_entries, + &resume_handle); + if (status == 0 || status == ERROR_MORE_DATA) { + switch (level) { + case 0: + info0 = (struct GROUP_INFO_0 *)buffer; + break; + case 1: + info1 = (struct GROUP_INFO_1 *)buffer; + break; + case 2: + info2 = (struct GROUP_INFO_2 *)buffer; + break; + case 3: + info3 = (struct GROUP_INFO_3 *)buffer; + break; + default: + return -1; + } + + for (i=0; igrpi0_name; + break; + case 1: + current_name = info1->grpi1_name; + break; + case 2: + current_name = info2->grpi2_name; + break; + case 3: + current_name = info3->grpi3_name; + break; + default: + break; + } + + if (strcasecmp(current_name, groupname) == 0) { + found_group = 1; + } + + switch (level) { + case 0: + info0++; + break; + case 1: + info1++; + break; + case 2: + info2++; + break; + case 3: + info3++; + break; + } + } + NetApiBufferFree(buffer); + } + } while (status == ERROR_MORE_DATA); + + if (status) { + return status; + } + + if (!found_group) { + torture_comment(tctx, "failed to get group\n"); + return -1; + } + + return 0; +} + +static NET_API_STATUS test_netgroupgetusers(struct torture_context *tctx, + const char *hostname, + uint32_t level, + const char *groupname, + const char *username) +{ + NET_API_STATUS status; + uint32_t entries_read = 0; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + int found_user = 0; + const char *current_name = NULL; + uint8_t *buffer = NULL; + int i; + + struct GROUP_USERS_INFO_0 *info0 = NULL; + struct GROUP_USERS_INFO_1 *info1 = NULL; + + torture_comment(tctx, "testing NetGroupGetUsers level %d\n", level); + + do { + status = NetGroupGetUsers(hostname, + groupname, + level, + &buffer, + (uint32_t)-1, + &entries_read, + &total_entries, + &resume_handle); + if (status == 0 || status == ERROR_MORE_DATA) { + + switch (level) { + case 0: + info0 = (struct GROUP_USERS_INFO_0 *)buffer; + break; + case 1: + info1 = (struct GROUP_USERS_INFO_1 *)buffer; + break; + default: + break; + } + for (i=0; igrui0_name; + break; + case 1: + current_name = info1->grui1_name; + break; + default: + break; + } + + if (username && strcasecmp(current_name, username) == 0) { + found_user = 1; + } + + switch (level) { + case 0: + info0++; + break; + case 1: + info1++; + break; + } + } + NetApiBufferFree(buffer); + } + } while (status == ERROR_MORE_DATA); + + if (status) { + return status; + } + + if (username && !found_user) { + torture_comment(tctx, "failed to get user\n"); + return -1; + } + + return 0; +} + +static NET_API_STATUS test_netgroupsetusers(struct torture_context *tctx, + const char *hostname, + const char *groupname, + uint32_t level, + size_t num_entries, + const char **names) +{ + NET_API_STATUS status; + uint8_t *buffer = NULL; + int i = 0; + size_t buf_size = 0; + + struct GROUP_USERS_INFO_0 *g0 = NULL; + struct GROUP_USERS_INFO_1 *g1 = NULL; + + torture_comment(tctx, "testing NetGroupSetUsers level %d\n", level); + + switch (level) { + case 0: + buf_size = sizeof(struct GROUP_USERS_INFO_0) * num_entries; + + status = NetApiBufferAllocate(buf_size, (void **)&g0); + if (status) { + goto out; + } + + for (i=0; i Date: Fri, 29 May 2009 16:59:35 +0200 Subject: s3-selftest: enable NETAPI-INITIALIZE and NETAPI-USER against samba3. Guenther --- source3/script/tests/test_posix_s3.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh index 83593dde4d..03e145d2c0 100755 --- a/source3/script/tests/test_posix_s3.sh +++ b/source3/script/tests/test_posix_s3.sh @@ -47,12 +47,15 @@ rpc="$rpc RPC-SCHANNEL RPC-SCHANNEL2 RPC-BENCH-SCHANNEL1" local="LOCAL-NSS-WRAPPER" +netapi="NETAPI-INITIALIZE NETAPI-USER" + + # NOTE: to enable the UNIX-WHOAMI test, we need to change the default share # config to allow guest access. I'm not sure whether this would break other # tests, so leaving it alone for now -- jpeach unix="UNIX-INFO2" -tests="$base $raw $rpc $unix $local" +tests="$base $raw $rpc $unix $local $netapi" if test "x$POSIX_SUBTESTS" != "x" ; then tests="$POSIX_SUBTESTS" -- cgit From 90db997d3737aed0dbe115a901a0e8f38ec5a2ac Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 18:11:39 +0200 Subject: Revert "s3-selftest: enable NETAPI-INITIALIZE and NETAPI-USER against samba3." This reverts commit 8da15dc29a920cd6f4d2ed96e8de4fbcd9d1ba11. --- source3/script/tests/test_posix_s3.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh index 03e145d2c0..83593dde4d 100755 --- a/source3/script/tests/test_posix_s3.sh +++ b/source3/script/tests/test_posix_s3.sh @@ -47,15 +47,12 @@ rpc="$rpc RPC-SCHANNEL RPC-SCHANNEL2 RPC-BENCH-SCHANNEL1" local="LOCAL-NSS-WRAPPER" -netapi="NETAPI-INITIALIZE NETAPI-USER" - - # NOTE: to enable the UNIX-WHOAMI test, we need to change the default share # config to allow guest access. I'm not sure whether this would break other # tests, so leaving it alone for now -- jpeach unix="UNIX-INFO2" -tests="$base $raw $rpc $unix $local $netapi" +tests="$base $raw $rpc $unix $local" if test "x$POSIX_SUBTESTS" != "x" ; then tests="$POSIX_SUBTESTS" -- cgit From 992e861a8d5244002fe6b0f73d4bb7bff1d8abb6 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 29 May 2009 14:06:50 +0200 Subject: s3 wbc_async: Fix copyright notice cut&paste error. Volker created all these prototypes, I just created the file and moved them over. Signed-off-by: Kai Blin --- source3/include/wbc_async.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/include/wbc_async.h b/source3/include/wbc_async.h index 57625d5baf..e2a6b99a22 100644 --- a/source3/include/wbc_async.h +++ b/source3/include/wbc_async.h @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Headers for the async winbind client library - Copyright (C) Kai Blin 2009 + Copyright (C) Volker Lendecke 2008 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 9d8766e176439cec3653b87ae93cbe917123c4ef Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 29 May 2009 14:14:50 +0200 Subject: async_sock: Change license to LGPLv3+ --- lib/async_req/async_sock.c | 20 ++++++++++++-------- lib/async_req/async_sock.h | 20 ++++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index fe71b29117..598a126467 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -3,17 +3,21 @@ async socket syscalls Copyright (C) Volker Lendecke 2008 - 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 3 of the License, or - (at your option) any later version. + ** NOTE! The following LGPL license applies to the async_sock + ** library. This does NOT imply that all of Samba is released + ** under the LGPL - This program is distributed in the hope that it will be useful, + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 General Public License for more details. + 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 General Public License + You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index a50e93238a..d47be30589 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -3,17 +3,21 @@ async socket operations Copyright (C) Volker Lendecke 2008 - 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 3 of the License, or - (at your option) any later version. + ** NOTE! The following LGPL license applies to the async_sock + ** library. This does NOT imply that all of Samba is released + ** under the LGPL - This program is distributed in the hope that it will be useful, + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 General Public License for more details. + 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 General Public License + You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ -- cgit From e3367284ab12f651a74f8d541565b23d51712841 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 29 May 2009 14:15:51 +0200 Subject: s3 async wbclient: Change license to LGPLv3+ --- source3/include/wbc_async.h | 20 ++++++++++++-------- source3/lib/wb_reqtrans.c | 20 ++++++++++++-------- source3/lib/wbclient.c | 20 ++++++++++++-------- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/source3/include/wbc_async.h b/source3/include/wbc_async.h index e2a6b99a22..96c5f8c348 100644 --- a/source3/include/wbc_async.h +++ b/source3/include/wbc_async.h @@ -3,17 +3,21 @@ Headers for the async winbind client library Copyright (C) Volker Lendecke 2008 - 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 3 of the License, or - (at your option) any later version. + ** NOTE! The following LGPL license applies to the wbclient + ** library. This does NOT imply that all of Samba is released + ** under the LGPL - This program is distributed in the hope that it will be useful, + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 General Public License for more details. + 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 General Public License + You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 55883ba8c7..7088925927 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -5,17 +5,21 @@ Copyright (C) Volker Lendecke 2008 - 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 3 of the License, or - (at your option) any later version. + ** NOTE! The following LGPL license applies to the wbclient + ** library. This does NOT imply that all of Samba is released + ** under the LGPL - This program is distributed in the hope that it will be useful, + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 General Public License for more details. + 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 General Public License + You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c index 164cfc9691..d0070ea349 100644 --- a/source3/lib/wbclient.c +++ b/source3/lib/wbclient.c @@ -3,17 +3,21 @@ Infrastructure for async winbind requests Copyright (C) Volker Lendecke 2008 - 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 3 of the License, or - (at your option) any later version. + ** NOTE! The following LGPL license applies to the wbclient + ** library. This does NOT imply that all of Samba is released + ** under the LGPL - This program is distributed in the hope that it will be useful, + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 General Public License for more details. + 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 General Public License + You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ -- cgit From 3d9e1f605ce6c9fe7240d21a4913459af18ed211 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 29 May 2009 18:28:36 +0200 Subject: util: Change license on tevent_unix to LGPLv3+ --- lib/util/tevent_unix.c | 20 ++++++++++++-------- lib/util/tevent_unix.h | 20 ++++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/lib/util/tevent_unix.c b/lib/util/tevent_unix.c index b89d5cd4d4..0a8c4c6b30 100644 --- a/lib/util/tevent_unix.c +++ b/lib/util/tevent_unix.c @@ -3,17 +3,21 @@ Wrap unix errno around tevent_req Copyright (C) Volker Lendecke 2009 - 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 3 of the License, or - (at your option) any later version. + ** NOTE! The following LGPL license applies to the tevent_unix + ** helper library. This does NOT imply that all of Samba is released + ** under the LGPL - This program is distributed in the hope that it will be useful, + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 General Public License for more details. + 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 General Public License + You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ diff --git a/lib/util/tevent_unix.h b/lib/util/tevent_unix.h index dc3ffaef33..bc2cea9199 100644 --- a/lib/util/tevent_unix.h +++ b/lib/util/tevent_unix.h @@ -3,17 +3,21 @@ Wrap unix errno around tevent_req Copyright (C) Volker Lendecke 2009 - 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 3 of the License, or - (at your option) any later version. + ** NOTE! The following LGPL license applies to the tevent_unix + ** helper library. This does NOT imply that all of Samba is released + ** under the LGPL - This program is distributed in the hope that it will be useful, + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 General Public License for more details. + 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 General Public License + You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ -- cgit From f451dd482d1220cb520bbf2cc210c458c25dca26 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 19:22:43 +0200 Subject: s4-smbtorture: fix the build w/o libnetapi. This is surely the wrong fix, but I could not figure out why the samba4 build system adds the init function although the m4 macro had switched off the torture libnetapi subsystem when the headers and libs were not found. Can one of the samba4 build gurus please have a look ? Guenther --- source4/torture/torture.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source4/torture/torture.c b/source4/torture/torture.c index de4fd591b9..d80acffa0d 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -45,6 +45,12 @@ bool torture_register_suite(struct torture_suite *suite) return torture_suite_add_suite(torture_root, suite); } +#ifndef HAVE_NETAPI_H +NTSTATUS torture_libnetapi_init(void) +{ + return NT_STATUS_OK; +} +#endif _PUBLIC_ int torture_init(void) { @@ -57,7 +63,9 @@ _PUBLIC_ int torture_init(void) extern NTSTATUS torture_rpc_init(void); extern NTSTATUS torture_smb2_init(void); extern NTSTATUS torture_net_init(void); +#ifdef HAVE_NETAPI_H extern NTSTATUS torture_libnetapi_init(void); +#endif extern NTSTATUS torture_raw_init(void); extern NTSTATUS torture_unix_init(void); extern NTSTATUS torture_winbind_init(void); -- cgit From dde62b35d7730d0c09b6479fab7baae809d2551e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 29 May 2009 21:27:53 +0200 Subject: Add smbldap_talloc_single_blob() --- source3/include/smbldap.h | 3 +++ source3/lib/smbldap.c | 31 +++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index c28d43d53b..7135c0be79 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -214,6 +214,9 @@ char * smbldap_talloc_single_attribute(LDAP *ldap_struct, LDAPMessage *entry, char * smbldap_talloc_smallest_attribute(LDAP *ldap_struct, LDAPMessage *entry, const char *attribute, TALLOC_CTX *mem_ctx); +bool smbldap_talloc_single_blob(TALLOC_CTX *mem_ctx, LDAP *ld, + LDAPMessage *msg, const char *attrib, + DATA_BLOB *blob); bool smbldap_pull_sid(LDAP *ld, LDAPMessage *msg, const char *attrib, struct dom_sid *sid); void talloc_autofree_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result); diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index b6921c329c..b3b5fa7582 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -389,23 +389,42 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { return result; } - bool smbldap_pull_sid(LDAP *ld, LDAPMessage *msg, const char *attrib, - struct dom_sid *sid) + bool smbldap_talloc_single_blob(TALLOC_CTX *mem_ctx, LDAP *ld, + LDAPMessage *msg, const char *attrib, + DATA_BLOB *blob) { struct berval **values; - bool ret = False; values = ldap_get_values_len(ld, msg, attrib); - if (!values) { return false; } - if (values[0] != NULL) { - ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); + if (ldap_count_values_len(values) != 1) { + DEBUG(10, ("Expected one value for %s, got %d\n", attrib, + ldap_count_values_len(values))); + return false; } + *blob = data_blob_talloc(mem_ctx, values[0]->bv_val, + values[0]->bv_len); ldap_value_free_len(values); + + return (blob->data != NULL); +} + + bool smbldap_pull_sid(LDAP *ld, LDAPMessage *msg, const char *attrib, + struct dom_sid *sid) +{ + DATA_BLOB blob; + bool ret; + + if (!smbldap_talloc_single_blob(talloc_tos(), ld, msg, attrib, + &blob)) { + return false; + } + ret = sid_parse((char *)blob.data, blob.length, sid); + TALLOC_FREE(blob.data); return ret; } -- cgit From 23e3b446893285cd0667e3168c503c7b57c2d3ff Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 29 May 2009 01:02:46 +0200 Subject: s3:pam_smbpass: make smb_update_db() static. Michael --- source3/pam_smbpass/pam_smb_passwd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/pam_smbpass/pam_smb_passwd.c b/source3/pam_smbpass/pam_smb_passwd.c index 9504e4d53c..0563af383c 100644 --- a/source3/pam_smbpass/pam_smb_passwd.c +++ b/source3/pam_smbpass/pam_smb_passwd.c @@ -45,7 +45,7 @@ #include "support.h" -int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user, const char *pass_new ) +static int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user, const char *pass_new ) { int retval; char *err_str = NULL; -- cgit From c3b67446d03957fc530afa079b344937253737ef Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 29 May 2009 01:08:36 +0200 Subject: libsmbclient: make SMBC_module_terminate() static. Michael --- source3/libsmb/libsmb_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index bacd907512..98885876b3 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -120,7 +120,7 @@ SMBC_module_init(void * punused) } -void +static void SMBC_module_terminate(void) { gencache_shutdown(); -- cgit From e31d4ee936cf8f7ec02770fa4b87fc821820b2ae Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 29 May 2009 01:12:47 +0200 Subject: s3:add prototype of map_nt_error_from_wbcErr() to proto.h Michael --- source3/include/proto.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index d5e403fa85..a0ff361411 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3001,6 +3001,7 @@ NTSTATUS dos_to_ntstatus(uint8 eclass, uint32 ecode); void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode); NTSTATUS werror_to_ntstatus(WERROR error); WERROR ntstatus_to_werror(NTSTATUS error); +NTSTATUS map_nt_error_from_wbcErr(wbcErr wbc_err); NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor); /* The following definitions come from libsmb/namecache.c */ -- cgit From 2b68fb7cb4ab5b76028c54ef163badd2952fe0c0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 29 May 2009 23:48:26 +0200 Subject: s3:pdbedit: fix "format not a string literal and no format arguments" warnings Michael --- source3/utils/pdbedit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 000f8c8d56..17175eb080 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -630,7 +630,7 @@ static int new_user(const char *username, const char *fullname, status = local_password_change(username, flags, pwd1, &err, &msg); if (!NT_STATUS_IS_OK(status)) { - if (err) fprintf(stderr, err); + if (err) fprintf(stderr, "%s", err); ret = -1; goto done; } @@ -738,7 +738,7 @@ static int new_machine(const char *machinename) print_user_info(name, True, False); ret = 0; } else { - if (err) fprintf(stderr, err); + if (err) fprintf(stderr, "%s", err); ret = -1; } -- cgit From 684d3dddd6d7d753f236e4c53893f993de2aa2b7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 29 May 2009 14:58:34 -0700 Subject: Make cli_nt_delete_on_close() async. Jeremy. --- source3/include/proto.h | 8 ++- source3/libsmb/clifile.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++ source3/torture/torture.c | 18 +++---- 3 files changed, 146 insertions(+), 10 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index a0ff361411..81d254f1ff 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2442,7 +2442,13 @@ struct tevent_req *cli_rmdir_send(TALLOC_CTX *mem_ctx, const char *dname); NTSTATUS cli_rmdir_recv(struct tevent_req *req); NTSTATUS cli_rmdir(struct cli_state *cli, const char *dname); -int cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag); +struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + bool flag); +NTSTATUS cli_nt_delete_on_close_recv(struct tevent_req *req); +NTSTATUS cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag); struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index f73428ee21..693d97626f 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1853,6 +1853,135 @@ NTSTATUS cli_rmdir(struct cli_state *cli, const char *dname) Set or clear the delete on close flag. ****************************************************************************/ +struct doc_state { + uint16_t setup; + uint8_t param[6]; + uint8_t data[1]; +}; + +static void cli_nt_delete_on_close_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct doc_state *state = tevent_req_data(req, struct doc_state); + NTSTATUS status; + + status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + tevent_req_done(req); +} + +struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + bool flag) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct doc_state *state = NULL; + + req = tevent_req_create(mem_ctx, &state, struct doc_state); + if (req == NULL) { + return NULL; + } + + /* Setup setup word. */ + SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO); + + /* Setup param array. */ + memset(state->param, '\0', 6); + SSVAL(state->param,0,fnum); + SSVAL(state->param,2,SMB_SET_FILE_DISPOSITION_INFO); + + /* Setup data array. */ + SCVAL(&state->data[0], 0, flag ? 1 : 0); + + subreq = cli_trans_send(state, /* mem ctx. */ + ev, /* event ctx. */ + cli, /* cli_state. */ + SMBtrans2, /* cmd. */ + NULL, /* pipe name. */ + -1, /* fid. */ + 0, /* function. */ + 0, /* flags. */ + &state->setup, /* setup. */ + 1, /* num setup uint16_t words. */ + 0, /* max returned setup. */ + state->param, /* param. */ + 6, /* num param. */ + 2, /* max returned param. */ + state->data, /* data. */ + 1, /* num data. */ + 0); /* max returned data. */ + + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_nt_delete_on_close_done, req); + return req; +} + +NTSTATUS cli_nt_delete_on_close_recv(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_nt_delete_on_close_send(frame, + ev, + cli, + fnum, + flag); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_nt_delete_on_close_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; +} + +#if 0 int cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag) { unsigned int data_len = 1; @@ -1889,6 +2018,7 @@ int cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag) return true; } +#endif struct cli_ntcreate_state { uint16_t vwv[24]; diff --git a/source3/torture/torture.c b/source3/torture/torture.c index b05ca44f0e..cfd3d640f9 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -3092,7 +3092,7 @@ static bool run_deletetest(int dummy) goto fail; } - if (!cli_nt_delete_on_close(cli1, fnum1, True)) { + if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) { printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1)); correct = False; goto fail; @@ -3145,7 +3145,7 @@ static bool run_deletetest(int dummy) goto fail; } - if (!cli_nt_delete_on_close(cli1, fnum1, True)) { + if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) { printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1)); correct = False; goto fail; @@ -3201,7 +3201,7 @@ static bool run_deletetest(int dummy) goto fail; } - if (!cli_nt_delete_on_close(cli1, fnum1, True)) { + if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) { printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1)); correct = False; goto fail; @@ -3235,7 +3235,7 @@ static bool run_deletetest(int dummy) /* This should fail - only allowed on NT opens with DELETE access. */ - if (cli_nt_delete_on_close(cli1, fnum1, True)) { + if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) { printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n"); correct = False; goto fail; @@ -3263,7 +3263,7 @@ static bool run_deletetest(int dummy) /* This should fail - only allowed on NT opens with DELETE access. */ - if (cli_nt_delete_on_close(cli1, fnum1, True)) { + if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) { printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n"); correct = False; goto fail; @@ -3288,13 +3288,13 @@ static bool run_deletetest(int dummy) goto fail; } - if (!cli_nt_delete_on_close(cli1, fnum1, True)) { + if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) { printf("[7] setting delete_on_close on file failed !\n"); correct = False; goto fail; } - if (!cli_nt_delete_on_close(cli1, fnum1, False)) { + if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) { printf("[7] unsetting delete_on_close on file failed !\n"); correct = False; goto fail; @@ -3350,7 +3350,7 @@ static bool run_deletetest(int dummy) goto fail; } - if (!cli_nt_delete_on_close(cli1, fnum1, True)) { + if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) { printf("[8] setting delete_on_close on file failed !\n"); correct = False; goto fail; @@ -3639,7 +3639,7 @@ static bool run_rename(int dummy) printf("Fourth open failed - %s\n", cli_errstr(cli1)); return False; } - if (!cli_nt_delete_on_close(cli1, fnum2, True)) { + if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) { printf("[8] setting delete_on_close on file failed !\n"); return False; } -- cgit From 8db4917290a2a69b7e0179649a37777d11e72f9d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 09:19:16 +0200 Subject: nss_wrapper: add support for getgrouplist. Guenther --- lib/nss_wrapper/nss_wrapper.c | 79 +++++++++++++++++++++++++++++++++++++++++++ lib/nss_wrapper/nss_wrapper.h | 6 ++++ 2 files changed, 85 insertions(+) diff --git a/lib/nss_wrapper/nss_wrapper.c b/lib/nss_wrapper/nss_wrapper.c index 1875dc3e4f..b62be61d12 100644 --- a/lib/nss_wrapper/nss_wrapper.c +++ b/lib/nss_wrapper/nss_wrapper.c @@ -90,6 +90,7 @@ #define real_initgroups_dyn initgroups_dyn */ #define real_initgroups initgroups +#define real_getgrouplist getgrouplist #define real_getgrnam getgrnam #define real_getgrnam_r getgrnam_r @@ -1222,3 +1223,81 @@ _PUBLIC_ void nwrap_endgrent(void) nwrap_files_endgrent(); } + +static int nwrap_files_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups) +{ + struct group *grp; + gid_t *groups_tmp; + int count = 1; + const char *name_of_group = NULL; + + NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__, user)); + + groups_tmp = (gid_t *)malloc(count * sizeof(gid_t)); + if (!groups_tmp) { + NWRAP_ERROR(("%s:calloc failed\n",__location__)); + errno = ENOMEM; + return -1; + } + + memcpy(groups_tmp, &group, sizeof(gid_t)); + + grp = nwrap_getgrgid(group); + if (grp) { + name_of_group = grp->gr_name; + } + + nwrap_files_setgrent(); + while ((grp = nwrap_files_getgrent()) != NULL) { + int i = 0; + + NWRAP_VERBOSE(("%s: inspecting %s for group membership\n", + __location__, grp->gr_name)); + + for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) { + + if ((strcmp(user, grp->gr_mem[i]) == 0) && + (strcmp(name_of_group, grp->gr_name) != 0)) { + + NWRAP_DEBUG(("%s: %s is member of %s\n", + __location__, user, grp->gr_name)); + + groups_tmp = (gid_t *)realloc(groups_tmp, (count + 1) * sizeof(gid_t)); + if (!groups_tmp) { + NWRAP_ERROR(("%s:calloc failed\n",__location__)); + errno = ENOMEM; + return -1; + } + + memcpy(&groups_tmp[count], &grp->gr_gid, sizeof(gid_t)); + count++; + } + } + } + nwrap_files_endgrent(); + + NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n", + __location__, user, *ngroups)); + + if (*ngroups < count) { + *ngroups = count; + free(groups_tmp); + return -1; + } + + *ngroups = count; + memcpy(groups, groups_tmp, count * sizeof(gid_t)); + free(groups_tmp); + + return count; +} + +_PUBLIC_ int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups) +{ + if (!nwrap_enabled()) { + return real_getgrouplist(user, group, groups, ngroups); + } + + return nwrap_files_getgrouplist(user, group, groups, ngroups); +} + diff --git a/lib/nss_wrapper/nss_wrapper.h b/lib/nss_wrapper/nss_wrapper.h index 35a47348a8..5bcd42ead4 100644 --- a/lib/nss_wrapper/nss_wrapper.h +++ b/lib/nss_wrapper/nss_wrapper.h @@ -46,6 +46,7 @@ int nwrap_getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp); void nwrap_endpwent(void); int nwrap_initgroups(const char *user, gid_t group); +int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups); struct group *nwrap_getgrnam(const char *name); int nwrap_getgrnam_r(const char *name, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp); @@ -120,6 +121,11 @@ void nwrap_endgrent(void); #endif #define initgroups nwrap_initgroups +#ifdef getgrouplist +#undef getgrouplist +#endif +#define getgrouplist nwrap_getgrouplist + #ifdef getgrnam #undef getgrnam #endif -- cgit From 62d1cd63758dea634defb4dc728febd247e49acd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 22:37:07 +0200 Subject: nss_wrapper: restructure parts of the testsuite. Guenther --- lib/nss_wrapper/testsuite.c | 105 ++++++++++++++++++++++++++++++-------------- 1 file changed, 72 insertions(+), 33 deletions(-) diff --git a/lib/nss_wrapper/testsuite.c b/lib/nss_wrapper/testsuite.c index 2a9cfaa391..b9c2b23eb0 100644 --- a/lib/nss_wrapper/testsuite.c +++ b/lib/nss_wrapper/testsuite.c @@ -116,75 +116,114 @@ static bool test_nwrap_getgrgid(struct torture_context *tctx, return grp ? true : false; } - -static bool test_nwrap_passwd(struct torture_context *tctx) +static bool test_nwrap_enum_passwd(struct torture_context *tctx, + struct passwd **pwd_array_p, + size_t *num_pwd_p) { struct passwd *pwd; - const char **names = NULL; - uid_t *uids = NULL; - int num_names = 0; - size_t num_uids = 0; - int i; + struct passwd *pwd_array = NULL; + size_t num_pwd = 0; torture_comment(tctx, "Testing setpwent\n"); setpwent(); - while ((pwd = getpwent())) { + while ((pwd = getpwent()) != NULL) { torture_comment(tctx, "Testing getpwent\n"); - if (pwd) { - print_passwd(pwd); - add_string_to_array(tctx, pwd->pw_name, &names, &num_names); - add_uid_to_array_unique(tctx, pwd->pw_uid, &uids, &num_uids); + print_passwd(pwd); + if (pwd_array_p && num_pwd_p) { + pwd_array = talloc_realloc(tctx, pwd_array, struct passwd, num_pwd+1); + torture_assert(tctx, pwd_array, "out of memory"); + pwd_array[num_pwd].pw_name = talloc_strdup(tctx, pwd->pw_name); + pwd_array[num_pwd].pw_uid = pwd->pw_uid; + pwd_array[num_pwd].pw_gid = pwd->pw_gid; + num_pwd++; } } torture_comment(tctx, "Testing endpwent\n"); endpwent(); - torture_assert_int_equal(tctx, num_names, num_uids, "invalid results"); + if (pwd_array_p) { + *pwd_array_p = pwd_array; + } + if (num_pwd_p) { + *num_pwd_p = num_pwd; + } + + return true; +} + +static bool test_nwrap_passwd(struct torture_context *tctx) +{ + int i; + struct passwd *pwd; + size_t num_pwd; + + torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd), + "failed to enumerate passwd"); - for (i=0; i < num_names; i++) { - torture_assert(tctx, test_nwrap_getpwnam(tctx, names[i]), + for (i=0; i < num_pwd; i++) { + torture_assert(tctx, test_nwrap_getpwnam(tctx, pwd[i].pw_name), "failed to call getpwnam for enumerated user"); - torture_assert(tctx, test_nwrap_getpwuid(tctx, uids[i]), + torture_assert(tctx, test_nwrap_getpwuid(tctx, pwd[i].pw_uid), "failed to call getpwuid for enumerated user"); } return true; } -static bool test_nwrap_group(struct torture_context *tctx) +static bool test_nwrap_enum_group(struct torture_context *tctx, + struct group **grp_array_p, + size_t *num_grp_p) { struct group *grp; - const char **names = NULL; - gid_t *gids = NULL; - int num_names = 0; - size_t num_gids = 0; - int i; + struct group *grp_array = NULL; + size_t num_grp = 0; torture_comment(tctx, "Testing setgrent\n"); setgrent(); - do { + while ((grp = getgrent()) != NULL) { torture_comment(tctx, "Testing getgrent\n"); - grp = getgrent(); - if (grp) { - print_group(grp); - add_string_to_array(tctx, grp->gr_name, &names, &num_names); - add_gid_to_array_unique(tctx, grp->gr_gid, &gids, &num_gids); + + print_group(grp); + if (grp_array_p && num_grp_p) { + grp_array = talloc_realloc(tctx, grp_array, struct group, num_grp+1); + torture_assert(tctx, grp_array, "out of memory"); + grp_array[num_grp].gr_name = talloc_strdup(tctx, grp->gr_name); + grp_array[num_grp].gr_gid = grp->gr_gid; + num_grp++; } - } while (grp); + } torture_comment(tctx, "Testing endgrent\n"); endgrent(); - torture_assert_int_equal(tctx, num_names, num_gids, "invalid results"); + if (grp_array_p) { + *grp_array_p = grp_array; + } + if (num_grp_p) { + *num_grp_p = num_grp; + } + + + return true; +} + +static bool test_nwrap_group(struct torture_context *tctx) +{ + int i; + struct group *grp; + size_t num_grp; + + torture_assert(tctx, test_nwrap_enum_group(tctx, &grp, &num_grp), + "failed to enumerate group"); - for (i=0; i < num_names; i++) { - torture_assert(tctx, test_nwrap_getgrnam(tctx, names[i]), + for (i=0; i < num_grp; i++) { + torture_assert(tctx, test_nwrap_getgrnam(tctx, grp[i].gr_name), "failed to call getgrnam for enumerated user"); - torture_assert(tctx, test_nwrap_getgrgid(tctx, gids[i]), + torture_assert(tctx, test_nwrap_getgrgid(tctx, grp[i].gr_gid), "failed to call getgrgid for enumerated user"); } -- cgit From 2be289c68da3a200dbeda2b8c00e74e4d8318693 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 May 2009 09:21:11 +0200 Subject: nss_wrapper: add test_nwrap_membership to testsuite. Guenther --- lib/nss_wrapper/testsuite.c | 74 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/lib/nss_wrapper/testsuite.c b/lib/nss_wrapper/testsuite.c index b9c2b23eb0..4f37354e12 100644 --- a/lib/nss_wrapper/testsuite.c +++ b/lib/nss_wrapper/testsuite.c @@ -230,6 +230,79 @@ static bool test_nwrap_group(struct torture_context *tctx) return true; } +static bool test_nwrap_getgrouplist(struct torture_context *tctx, + const char *user, + gid_t gid, + gid_t **gids_p, + int *num_gids_p) +{ + int ret; + int num_groups = 0; + gid_t *groups = NULL; + + torture_comment(tctx, "Testing getgrouplist: %s\n", user); + + ret = getgrouplist(user, gid, NULL, &num_groups); + if (ret == -1 || num_groups != 0) { + + groups = talloc_array(tctx, gid_t, num_groups); + torture_assert(tctx, groups, "out of memory\n"); + + ret = getgrouplist(user, gid, groups, &num_groups); + } + + torture_assert(tctx, (ret != -1), "failed to call getgrouplist"); + + torture_comment(tctx, "%s is member in %d groups\n", user, num_groups); + + if (gids_p) { + *gids_p = groups; + } + if (num_gids_p) { + *num_gids_p = num_groups; + } + + return true; +} + +static bool test_nwrap_membership(struct torture_context *tctx) +{ + const char *old_pwd = getenv("NSS_WRAPPER_PASSWD"); + const char *old_group = getenv("NSS_WRAPPER_GROUP"); + struct passwd *pwd; + size_t num_pwd; + int i; + + if (!old_pwd || !old_group) { + torture_skip(tctx, "nothing to test\n"); + return true; + } + + torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd), + "failed to enumerate passwd"); + + for (i=0; i < num_pwd; i++) { + + int num_user_groups = 0; + gid_t *user_groups = NULL; + int g; + + torture_assert(tctx, test_nwrap_getgrouplist(tctx, + pwd[i].pw_name, + pwd[i].pw_gid, + &user_groups, + &num_user_groups), + "failed to test getgrouplist"); + + for (g=0; g < num_user_groups; g++) { + torture_assert(tctx, test_nwrap_getgrgid(tctx, user_groups[g]), + "failed to find the group the user is a member of"); + } + } + + return true; +} + static bool test_nwrap_env(struct torture_context *tctx) { const char *old_pwd = getenv("NSS_WRAPPER_PASSWD"); @@ -253,6 +326,7 @@ struct torture_suite *torture_local_nss_wrapper(TALLOC_CTX *mem_ctx) struct torture_suite *suite = torture_suite_create(mem_ctx, "NSS-WRAPPER"); torture_suite_add_simple_test(suite, "env", test_nwrap_env); + torture_suite_add_simple_test(suite, "membership", test_nwrap_membership); return suite; } -- cgit From 590a3afc8a22658075235b5b5eb30e977999b3a8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 May 2009 15:46:35 +0200 Subject: Re-Add the "dropbox" functionality with -wx rights on a directory --- source3/smbd/filename.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 72b4ab7aa6..bcd8560ad9 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -524,12 +524,12 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, errno == ELOOP) { result = NT_STATUS_OBJECT_PATH_NOT_FOUND; - } - else { + goto fail; + } else if (errno != EACCES) { result = map_nt_error_from_unix(errno); + goto fail; } - goto fail; } /* -- cgit From 57ea909b327812479e9c61f0398f257023a504b4 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Thu, 16 Apr 2009 14:53:36 +0200 Subject: libwbclient: Add async call framework. --- lib/async_req/async_sock.c | 4 +- lib/async_req/config.mk | 1 + nsswitch/config.mk | 6 +- nsswitch/libwbclient/config.mk | 15 + nsswitch/libwbclient/libwbclient.h | 1 + nsswitch/libwbclient/wb_reqtrans.c | 445 ++++++++++++++++++++ nsswitch/libwbclient/wbc_async.c | 687 +++++++++++++++++++++++++++++++ nsswitch/libwbclient/wbc_async.h | 79 ++++ nsswitch/libwbclient/wbclient.c | 2 + nsswitch/libwbclient/wbclient_internal.h | 1 - nsswitch/winbind_struct_protocol.h | 5 + source3/Makefile.in | 10 +- source3/include/wbc_async.h | 75 ---- source3/lib/wb_reqtrans.c | 433 ------------------- source3/lib/wbclient.c | 678 ------------------------------ source3/samba4.mk | 1 + source3/torture/torture.c | 2 +- source4/Makefile | 1 + source4/libcli/wbclient/config.mk | 4 +- source4/main.mk | 1 + source4/ntvfs/posix/config.mk | 2 +- source4/rpc_server/config.mk | 2 +- 22 files changed, 1257 insertions(+), 1198 deletions(-) create mode 100644 nsswitch/libwbclient/config.mk create mode 100644 nsswitch/libwbclient/wb_reqtrans.c create mode 100644 nsswitch/libwbclient/wbc_async.c create mode 100644 nsswitch/libwbclient/wbc_async.h delete mode 100644 source3/include/wbc_async.h delete mode 100644 source3/lib/wb_reqtrans.c delete mode 100644 source3/lib/wbclient.c diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 598a126467..09eec10fc5 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -426,7 +426,7 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, to_write += state->iov[i].iov_len; } - written = sys_writev(state->fd, state->iov, state->count); + written = writev(state->fd, state->iov, state->count); if (written == -1) { tevent_req_error(req, errno); return; @@ -570,7 +570,7 @@ static void read_packet_handler(struct tevent_context *ev, return; } - tmp = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t, total+more); + tmp = talloc_realloc(state, state->buf, uint8_t, total+more); if (tevent_req_nomem(tmp, req)) { return; } diff --git a/lib/async_req/config.mk b/lib/async_req/config.mk index bf0fd6a2db..1f4b557ce4 100644 --- a/lib/async_req/config.mk +++ b/lib/async_req/config.mk @@ -1,3 +1,4 @@ [SUBSYSTEM::LIBASYNC_REQ] +PUBLIC_DEPENDENCIES = LIBREPLACE_NETWORK LIBASYNC_REQ_OBJ_FILES = $(addprefix ../lib/async_req/, async_sock.o) diff --git a/nsswitch/config.mk b/nsswitch/config.mk index 3a4f054d1f..264032e530 100644 --- a/nsswitch/config.mk +++ b/nsswitch/config.mk @@ -26,7 +26,11 @@ PRIVATE_DEPENDENCIES = \ LIBCLI_AUTH \ LIBPOPT \ POPT_SAMBA \ - LIBWINBIND-CLIENT + LIBWINBIND-CLIENT \ + LIBWBCLIENT \ + LIBTEVENT \ + UTIL_TEVENT \ + LIBASYNC_REQ # End BINARY nsstest ################################# diff --git a/nsswitch/libwbclient/config.mk b/nsswitch/libwbclient/config.mk new file mode 100644 index 0000000000..ffdab159f8 --- /dev/null +++ b/nsswitch/libwbclient/config.mk @@ -0,0 +1,15 @@ +[SUBSYSTEM::LIBWBCLIENT] +PUBLIC_DEPENDENCIES = LIBASYNC_REQ \ + LIBTEVENT \ + LIBTALLOC \ + UTIL_TEVENT + +LIBWBCLIENT_OBJ_FILES = $(addprefix $(libwbclientsrcdir)/, wbc_async.o \ + wbc_guid.o \ + wbc_idmap.o \ + wbclient.o \ + wbc_pam.o \ + wbc_pwd.o \ + wbc_sid.o \ + wbc_util.o \ + wb_reqtrans.o ) diff --git a/nsswitch/libwbclient/libwbclient.h b/nsswitch/libwbclient/libwbclient.h index 74cba7e796..5a25cf462c 100644 --- a/nsswitch/libwbclient/libwbclient.h +++ b/nsswitch/libwbclient/libwbclient.h @@ -36,6 +36,7 @@ /* Public headers */ #include "wbclient.h" +#include "wbc_async.h" /* Private headers */ diff --git a/nsswitch/libwbclient/wb_reqtrans.c b/nsswitch/libwbclient/wb_reqtrans.c new file mode 100644 index 0000000000..84ed7198f2 --- /dev/null +++ b/nsswitch/libwbclient/wb_reqtrans.c @@ -0,0 +1,445 @@ +/* + Unix SMB/CIFS implementation. + + Async transfer of winbindd_request and _response structs + + Copyright (C) Volker Lendecke 2008 + + ** NOTE! The following LGPL license applies to the wbclient + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 Lesser General Public License + along with this program. If not, see . +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/network.h" +#include +#include +struct fd_event; +struct event_context; +#include "lib/async_req/async_sock.h" +#include "lib/util/tevent_unix.h" +#include "nsswitch/winbind_struct_protocol.h" +#include "nsswitch/libwbclient/wbclient.h" +#include "nsswitch/libwbclient/wbc_async.h" + +#ifdef DBGC_CLASS +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_WINBIND +#endif + +struct req_read_state { + struct winbindd_request *wb_req; + size_t max_extra_data; + ssize_t ret; +}; + +static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data); +static void wb_req_read_done(struct tevent_req *subreq); + +struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t max_extra_data) +{ + struct tevent_req *req, *subreq; + struct req_read_state *state; + + req = tevent_req_create(mem_ctx, &state, struct req_read_state); + if (req == NULL) { + return NULL; + } + state->max_extra_data = max_extra_data; + + subreq = read_packet_send(state, ev, fd, 4, wb_req_more, state); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, wb_req_read_done, req); + return req; +} + +static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data) +{ + struct req_read_state *state = talloc_get_type_abort( + private_data, struct req_read_state); + struct winbindd_request *req = (struct winbindd_request *)buf; + + if (buflen == 4) { + if (req->length != sizeof(struct winbindd_request)) { + DEBUG(0, ("wb_req_read_len: Invalid request size " + "received: %d (expected %d)\n", + (int)req->length, + (int)sizeof(struct winbindd_request))); + return -1; + } + return sizeof(struct winbindd_request) - 4; + } + + if ((state->max_extra_data != 0) + && (req->extra_len > state->max_extra_data)) { + DEBUG(3, ("Got request with %d bytes extra data on " + "unprivileged socket\n", (int)req->extra_len)); + return -1; + } + + return req->extra_len; +} + +static void wb_req_read_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct req_read_state *state = tevent_req_data( + req, struct req_read_state); + int err; + uint8_t *buf; + + state->ret = read_packet_recv(subreq, state, &buf, &err); + TALLOC_FREE(subreq); + if (state->ret == -1) { + tevent_req_error(req, err); + return; + } + + state->wb_req = (struct winbindd_request *)buf; + + if (state->wb_req->extra_len != 0) { + state->wb_req->extra_data.data = + (char *)buf + sizeof(struct winbindd_request); + } else { + state->wb_req->extra_data.data = NULL; + } + tevent_req_done(req); +} + +ssize_t wb_req_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct winbindd_request **preq, int *err) +{ + struct req_read_state *state = tevent_req_data( + req, struct req_read_state); + + if (tevent_req_is_unix_error(req, err)) { + return -1; + } + *preq = talloc_move(mem_ctx, &state->wb_req); + return state->ret; +} + +struct req_write_state { + struct iovec iov[2]; + ssize_t ret; +}; + +static void wb_req_write_done(struct tevent_req *subreq); + +struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_request *wb_req) +{ + struct tevent_req *req, *subreq; + struct req_write_state *state; + int count = 1; + + req = tevent_req_create(mem_ctx, &state, struct req_write_state); + if (req == NULL) { + return NULL; + } + + state->iov[0].iov_base = (void *)wb_req; + state->iov[0].iov_len = sizeof(struct winbindd_request); + + if (wb_req->extra_len != 0) { + state->iov[1].iov_base = (void *)wb_req->extra_data.data; + state->iov[1].iov_len = wb_req->extra_len; + count = 2; + } + + subreq = writev_send(state, ev, queue, fd, true, state->iov, count); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, wb_req_write_done, req); + return req; +} + +static void wb_req_write_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct req_write_state *state = tevent_req_data( + req, struct req_write_state); + int err; + + state->ret = writev_recv(subreq, &err); + TALLOC_FREE(subreq); + if (state->ret < 0) { + tevent_req_error(req, err); + return; + } + tevent_req_done(req); +} + +ssize_t wb_req_write_recv(struct tevent_req *req, int *err) +{ + struct req_write_state *state = tevent_req_data( + req, struct req_write_state); + + if (tevent_req_is_unix_error(req, err)) { + return -1; + } + return state->ret; +} + +struct resp_read_state { + struct winbindd_response *wb_resp; + ssize_t ret; +}; + +static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data); +static void wb_resp_read_done(struct tevent_req *subreq); + +struct tevent_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, int fd) +{ + struct tevent_req *req, *subreq; + struct resp_read_state *state; + + req = tevent_req_create(mem_ctx, &state, struct resp_read_state); + if (req == NULL) { + return NULL; + } + + subreq = read_packet_send(state, ev, fd, 4, wb_resp_more, state); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, wb_resp_read_done, req); + return req; +} + +static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data) +{ + struct winbindd_response *resp = (struct winbindd_response *)buf; + + if (buflen == 4) { + if (resp->length < sizeof(struct winbindd_response)) { + DEBUG(0, ("wb_resp_read_len: Invalid response size " + "received: %d (expected at least%d)\n", + (int)resp->length, + (int)sizeof(struct winbindd_response))); + return -1; + } + } + return resp->length - buflen; +} + +static void wb_resp_read_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct resp_read_state *state = tevent_req_data( + req, struct resp_read_state); + uint8_t *buf; + int err; + + state->ret = read_packet_recv(subreq, state, &buf, &err); + TALLOC_FREE(subreq); + if (state->ret == -1) { + tevent_req_error(req, err); + return; + } + + state->wb_resp = (struct winbindd_response *)buf; + + if (state->wb_resp->length > sizeof(struct winbindd_response)) { + state->wb_resp->extra_data.data = + (char *)buf + sizeof(struct winbindd_response); + } else { + state->wb_resp->extra_data.data = NULL; + } + tevent_req_done(req); +} + +ssize_t wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct winbindd_response **presp, int *err) +{ + struct resp_read_state *state = tevent_req_data( + req, struct resp_read_state); + + if (tevent_req_is_unix_error(req, err)) { + return -1; + } + *presp = talloc_move(mem_ctx, &state->wb_resp); + return state->ret; +} + +struct resp_write_state { + struct iovec iov[2]; + ssize_t ret; +}; + +static void wb_resp_write_done(struct tevent_req *subreq); + +struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_response *wb_resp) +{ + struct tevent_req *req, *subreq; + struct resp_write_state *state; + int count = 1; + + req = tevent_req_create(mem_ctx, &state, struct resp_write_state); + if (req == NULL) { + return NULL; + } + + state->iov[0].iov_base = (void *)wb_resp; + state->iov[0].iov_len = sizeof(struct winbindd_response); + + if (wb_resp->length > sizeof(struct winbindd_response)) { + state->iov[1].iov_base = (void *)wb_resp->extra_data.data; + state->iov[1].iov_len = + wb_resp->length - sizeof(struct winbindd_response); + count = 2; + } + + subreq = writev_send(state, ev, queue, fd, true, state->iov, count); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, wb_resp_write_done, req); + return req; +} + +static void wb_resp_write_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct resp_write_state *state = tevent_req_data( + req, struct resp_write_state); + int err; + + state->ret = writev_recv(subreq, &err); + TALLOC_FREE(subreq); + if (state->ret < 0) { + tevent_req_error(req, err); + return; + } + tevent_req_done(req); +} + +ssize_t wb_resp_write_recv(struct tevent_req *req, int *err) +{ + struct resp_write_state *state = tevent_req_data( + req, struct resp_write_state); + + if (tevent_req_is_unix_error(req, err)) { + return -1; + } + return state->ret; +} + +struct wb_simple_trans_state { + struct tevent_context *ev; + int fd; + struct winbindd_response *wb_resp; +}; + +static void wb_simple_trans_write_done(struct tevent_req *subreq); +static void wb_simple_trans_read_done(struct tevent_req *subreq); + +struct tevent_req *wb_simple_trans_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_request *wb_req) +{ + struct tevent_req *req, *subreq; + struct wb_simple_trans_state *state; + + req = tevent_req_create(mem_ctx, &state, struct wb_simple_trans_state); + if (req == NULL) { + return NULL; + } + + wb_req->length = sizeof(struct winbindd_request); + + state->ev = ev; + state->fd = fd; + + subreq = wb_req_write_send(state, ev, queue, fd, wb_req); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, wb_simple_trans_write_done, req); + + return req; +} + +static void wb_simple_trans_write_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_simple_trans_state *state = tevent_req_data( + req, struct wb_simple_trans_state); + ssize_t ret; + int err; + + ret = wb_req_write_recv(subreq, &err); + TALLOC_FREE(subreq); + if (ret == -1) { + tevent_req_error(req, err); + return; + } + subreq = wb_resp_read_send(state, state->ev, state->fd); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, wb_simple_trans_read_done, req); +} + +static void wb_simple_trans_read_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_simple_trans_state *state = tevent_req_data( + req, struct wb_simple_trans_state); + ssize_t ret; + int err; + + ret = wb_resp_read_recv(subreq, state, &state->wb_resp, &err); + TALLOC_FREE(subreq); + if (ret == -1) { + tevent_req_error(req, err); + return; + } + + tevent_req_done(req); +} + +int wb_simple_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct winbindd_response **presponse, int *err) +{ + struct wb_simple_trans_state *state = tevent_req_data( + req, struct wb_simple_trans_state); + + if (tevent_req_is_unix_error(req, err)) { + return -1; + } + *presponse = talloc_move(mem_ctx, &state->wb_resp); + return 0; +} diff --git a/nsswitch/libwbclient/wbc_async.c b/nsswitch/libwbclient/wbc_async.c new file mode 100644 index 0000000000..141c9816aa --- /dev/null +++ b/nsswitch/libwbclient/wbc_async.c @@ -0,0 +1,687 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async winbind requests + Copyright (C) Volker Lendecke 2008 + + ** NOTE! The following LGPL license applies to the wbclient + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 Lesser General Public License + along with this program. If not, see . +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/network.h" +#include +#include +struct fd_event; +struct event_context; +#include "lib/async_req/async_sock.h" +#include "nsswitch/winbind_struct_protocol.h" +#include "nsswitch/libwbclient/wbclient.h" +#include "nsswitch/libwbclient/wbc_async.h" + +wbcErr map_wbc_err_from_errno(int error) +{ + switch(error) { + case EPERM: + case EACCES: + return WBC_ERR_AUTH_ERROR; + case ENOMEM: + return WBC_ERR_NO_MEMORY; + case EIO: + default: + return WBC_ERR_UNKNOWN_FAILURE; + } +} + +bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err) +{ + enum tevent_req_state state; + uint64_t error; + if (!tevent_req_is_error(req, &state, &error)) { + *pwbc_err = WBC_ERR_SUCCESS; + return false; + } + + switch (state) { + case TEVENT_REQ_USER_ERROR: + *pwbc_err = error; + break; + case TEVENT_REQ_TIMED_OUT: + *pwbc_err = WBC_ERR_UNKNOWN_FAILURE; + break; + case TEVENT_REQ_NO_MEMORY: + *pwbc_err = WBC_ERR_NO_MEMORY; + break; + default: + *pwbc_err = WBC_ERR_UNKNOWN_FAILURE; + break; + } + return true; +} + +wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req) +{ + wbcErr wbc_err; + + if (tevent_req_is_wbcerr(req, &wbc_err)) { + return wbc_err; + } + + return WBC_ERR_SUCCESS; +} + +struct wb_context { + struct tevent_queue *queue; + int fd; + bool is_priv; +}; + +static int make_nonstd_fd(int fd) +{ + int i; + int sys_errno = 0; + int fds[3]; + int num_fds = 0; + + if (fd == -1) { + return -1; + } + while (fd < 3) { + fds[num_fds++] = fd; + fd = dup(fd); + if (fd == -1) { + sys_errno = errno; + break; + } + } + for (i=0; i= 0) { + flags |= FD_CLOEXEC; + result = fcntl( new_fd, F_SETFD, flags ); + } + if (result < 0) { + goto fail; + } +#endif + return new_fd; + + fail: + if (new_fd != -1) { + int sys_errno = errno; + close(new_fd); + errno = sys_errno; + } + return -1; +} + +struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx) +{ + struct wb_context *result; + + result = talloc(mem_ctx, struct wb_context); + if (result == NULL) { + return NULL; + } + result->queue = tevent_queue_create(result, "wb_trans"); + if (result->queue == NULL) { + TALLOC_FREE(result); + return NULL; + } + result->fd = -1; + result->is_priv = false; + return result; +} + +struct wb_connect_state { + int dummy; +}; + +static void wbc_connect_connected(struct tevent_req *subreq); + +static struct tevent_req *wb_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, + const char *dir) +{ + struct tevent_req *result, *subreq; + struct wb_connect_state *state; + struct sockaddr_un sunaddr; + struct stat st; + char *path = NULL; + wbcErr wbc_err; + + result = tevent_req_create(mem_ctx, &state, struct wb_connect_state); + if (result == NULL) { + return NULL; + } + + if (wb_ctx->fd != -1) { + close(wb_ctx->fd); + wb_ctx->fd = -1; + } + + /* Check permissions on unix socket directory */ + + if (lstat(dir, &st) == -1) { + wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE; + goto post_status; + } + + if (!S_ISDIR(st.st_mode) || + (st.st_uid != 0 && st.st_uid != geteuid())) { + wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE; + goto post_status; + } + + /* Connect to socket */ + + path = talloc_asprintf(talloc_tos(), "%s/%s", dir, + WINBINDD_SOCKET_NAME); + if (path == NULL) { + goto nomem; + } + + sunaddr.sun_family = AF_UNIX; + strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)); + TALLOC_FREE(path); + + /* If socket file doesn't exist, don't bother trying to connect + with retry. This is an attempt to make the system usable when + the winbindd daemon is not running. */ + + if ((lstat(sunaddr.sun_path, &st) == -1) + || !S_ISSOCK(st.st_mode) + || (st.st_uid != 0 && st.st_uid != geteuid())) { + wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE; + goto post_status; + } + + wb_ctx->fd = make_safe_fd(socket(AF_UNIX, SOCK_STREAM, 0)); + if (wb_ctx->fd == -1) { + wbc_err = map_wbc_err_from_errno(errno); + goto post_status; + } + + subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd, + (struct sockaddr *)(void *)&sunaddr, + sizeof(sunaddr)); + if (subreq == NULL) { + goto nomem; + } + tevent_req_set_callback(subreq, wbc_connect_connected, result); + return result; + + post_status: + tevent_req_error(result, wbc_err); + return tevent_req_post(result, ev); + nomem: + TALLOC_FREE(result); + return NULL; +} + +static void wbc_connect_connected(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + int res, err; + + res = async_connect_recv(subreq, &err); + TALLOC_FREE(subreq); + if (res == -1) { + tevent_req_error(req, map_wbc_err_from_errno(err)); + return; + } + tevent_req_done(req); +} + +static wbcErr wb_connect_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_wbcerr(req); +} + +static const char *winbindd_socket_dir(void) +{ +#ifdef SOCKET_WRAPPER + const char *env_dir; + + env_dir = getenv(WINBINDD_SOCKET_DIR_ENVVAR); + if (env_dir) { + return env_dir; + } +#endif + + return WINBINDD_SOCKET_DIR; +} + +struct wb_open_pipe_state { + struct wb_context *wb_ctx; + struct tevent_context *ev; + bool need_priv; + struct winbindd_request wb_req; +}; + +static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq); +static void wb_open_pipe_ping_done(struct tevent_req *subreq); +static void wb_open_pipe_getpriv_done(struct tevent_req *subreq); +static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq); + +static struct tevent_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, + bool need_priv) +{ + struct tevent_req *result, *subreq; + struct wb_open_pipe_state *state; + + result = tevent_req_create(mem_ctx, &state, struct wb_open_pipe_state); + if (result == NULL) { + return NULL; + } + state->wb_ctx = wb_ctx; + state->ev = ev; + state->need_priv = need_priv; + + if (wb_ctx->fd != -1) { + close(wb_ctx->fd); + wb_ctx->fd = -1; + } + + subreq = wb_connect_send(state, ev, wb_ctx, winbindd_socket_dir()); + if (subreq == NULL) { + goto fail; + } + tevent_req_set_callback(subreq, wb_open_pipe_connect_nonpriv_done, + result); + return result; + + fail: + TALLOC_FREE(result); + return NULL; +} + +static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_open_pipe_state *state = tevent_req_data( + req, struct wb_open_pipe_state); + wbcErr wbc_err; + + wbc_err = wb_connect_recv(subreq); + TALLOC_FREE(subreq); + if (!WBC_ERROR_IS_OK(wbc_err)) { + state->wb_ctx->is_priv = true; + tevent_req_error(req, wbc_err); + return; + } + + ZERO_STRUCT(state->wb_req); + state->wb_req.cmd = WINBINDD_INTERFACE_VERSION; + state->wb_req.pid = getpid(); + + subreq = wb_simple_trans_send(state, state->ev, NULL, + state->wb_ctx->fd, &state->wb_req); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, wb_open_pipe_ping_done, req); +} + +static void wb_open_pipe_ping_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_open_pipe_state *state = tevent_req_data( + req, struct wb_open_pipe_state); + struct winbindd_response *wb_resp; + int ret, err; + + ret = wb_simple_trans_recv(subreq, state, &wb_resp, &err); + TALLOC_FREE(subreq); + if (ret == -1) { + tevent_req_error(req, map_wbc_err_from_errno(err)); + return; + } + + if (!state->need_priv) { + tevent_req_done(req); + return; + } + + state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR; + state->wb_req.pid = getpid(); + + subreq = wb_simple_trans_send(state, state->ev, NULL, + state->wb_ctx->fd, &state->wb_req); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, wb_open_pipe_getpriv_done, req); +} + +static void wb_open_pipe_getpriv_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_open_pipe_state *state = tevent_req_data( + req, struct wb_open_pipe_state); + struct winbindd_response *wb_resp = NULL; + int ret, err; + + ret = wb_simple_trans_recv(subreq, state, &wb_resp, &err); + TALLOC_FREE(subreq); + if (ret == -1) { + tevent_req_error(req, map_wbc_err_from_errno(err)); + return; + } + + close(state->wb_ctx->fd); + state->wb_ctx->fd = -1; + + subreq = wb_connect_send(state, state->ev, state->wb_ctx, + (char *)wb_resp->extra_data.data); + TALLOC_FREE(wb_resp); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, wb_open_pipe_connect_priv_done, req); +} + +static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_open_pipe_state *state = tevent_req_data( + req, struct wb_open_pipe_state); + wbcErr wbc_err; + + wbc_err = wb_connect_recv(subreq); + TALLOC_FREE(subreq); + if (!WBC_ERROR_IS_OK(wbc_err)) { + tevent_req_error(req, wbc_err); + return; + } + state->wb_ctx->is_priv = true; + tevent_req_done(req); +} + +static wbcErr wb_open_pipe_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_wbcerr(req); +} + +struct wb_trans_state { + struct wb_trans_state *prev, *next; + struct wb_context *wb_ctx; + struct tevent_context *ev; + struct winbindd_request *wb_req; + struct winbindd_response *wb_resp; + bool need_priv; +}; + +static bool closed_fd(int fd) +{ + struct timeval tv; + fd_set r_fds; + int selret; + + if (fd == -1) { + return true; + } + + FD_ZERO(&r_fds); + FD_SET(fd, &r_fds); + ZERO_STRUCT(tv); + + selret = select(fd+1, &r_fds, NULL, NULL, &tv); + if (selret == -1) { + return true; + } + if (selret == 0) { + return false; + } + return (FD_ISSET(fd, &r_fds)); +} + +static void wb_trans_trigger(struct tevent_req *req, void *private_data); +static void wb_trans_connect_done(struct tevent_req *subreq); +static void wb_trans_done(struct tevent_req *subreq); +static void wb_trans_retry_wait_done(struct tevent_req *subreq); + +struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, bool need_priv, + struct winbindd_request *wb_req) +{ + struct tevent_req *req; + struct wb_trans_state *state; + + req = tevent_req_create(mem_ctx, &state, struct wb_trans_state); + if (req == NULL) { + return NULL; + } + state->wb_ctx = wb_ctx; + state->ev = ev; + state->wb_req = wb_req; + state->need_priv = need_priv; + + if (!tevent_queue_add(wb_ctx->queue, ev, req, wb_trans_trigger, + NULL)) { + tevent_req_nomem(NULL, req); + return tevent_req_post(req, ev); + } + return req; +} + +static void wb_trans_trigger(struct tevent_req *req, void *private_data) +{ + struct wb_trans_state *state = tevent_req_data( + req, struct wb_trans_state); + struct tevent_req *subreq; + + if ((state->wb_ctx->fd != -1) && closed_fd(state->wb_ctx->fd)) { + close(state->wb_ctx->fd); + state->wb_ctx->fd = -1; + } + + if ((state->wb_ctx->fd == -1) + || (state->need_priv && !state->wb_ctx->is_priv)) { + subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx, + state->need_priv); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, wb_trans_connect_done, req); + return; + } + + state->wb_req->pid = getpid(); + + subreq = wb_simple_trans_send(state, state->ev, NULL, + state->wb_ctx->fd, state->wb_req); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, wb_trans_done, req); +} + +static bool wb_trans_retry(struct tevent_req *req, + struct wb_trans_state *state, + wbcErr wbc_err) +{ + struct tevent_req *subreq; + + if (WBC_ERROR_IS_OK(wbc_err)) { + return false; + } + + if (wbc_err == WBC_ERR_WINBIND_NOT_AVAILABLE) { + /* + * Winbind not around or we can't connect to the pipe. Fail + * immediately. + */ + tevent_req_error(req, wbc_err); + return true; + } + + /* + * The transfer as such failed, retry after one second + */ + + if (state->wb_ctx->fd != -1) { + close(state->wb_ctx->fd); + state->wb_ctx->fd = -1; + } + + subreq = tevent_wakeup_send(state, state->ev, + timeval_current_ofs(1, 0)); + if (tevent_req_nomem(subreq, req)) { + return true; + } + tevent_req_set_callback(subreq, wb_trans_retry_wait_done, req); + return true; +} + +static void wb_trans_retry_wait_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_trans_state *state = tevent_req_data( + req, struct wb_trans_state); + bool ret; + + ret = tevent_wakeup_recv(subreq); + TALLOC_FREE(subreq); + if (!ret) { + tevent_req_error(req, WBC_ERR_UNKNOWN_FAILURE); + return; + } + + subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx, + state->need_priv); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, wb_trans_connect_done, req); +} + +static void wb_trans_connect_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_trans_state *state = tevent_req_data( + req, struct wb_trans_state); + wbcErr wbc_err; + + wbc_err = wb_open_pipe_recv(subreq); + TALLOC_FREE(subreq); + + if (wb_trans_retry(req, state, wbc_err)) { + return; + } + + subreq = wb_simple_trans_send(state, state->ev, NULL, + state->wb_ctx->fd, state->wb_req); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, wb_trans_done, req); +} + +static void wb_trans_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_trans_state *state = tevent_req_data( + req, struct wb_trans_state); + int ret, err; + + ret = wb_simple_trans_recv(subreq, state, &state->wb_resp, &err); + TALLOC_FREE(subreq); + if ((ret == -1) + && wb_trans_retry(req, state, map_wbc_err_from_errno(err))) { + return; + } + + tevent_req_done(req); +} + +wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct winbindd_response **presponse) +{ + struct wb_trans_state *state = tevent_req_data( + req, struct wb_trans_state); + wbcErr wbc_err; + + if (tevent_req_is_wbcerr(req, &wbc_err)) { + return wbc_err; + } + + *presponse = talloc_move(mem_ctx, &state->wb_resp); + return WBC_ERR_SUCCESS; +} diff --git a/nsswitch/libwbclient/wbc_async.h b/nsswitch/libwbclient/wbc_async.h new file mode 100644 index 0000000000..a2e0eed448 --- /dev/null +++ b/nsswitch/libwbclient/wbc_async.h @@ -0,0 +1,79 @@ +/* + Unix SMB/CIFS implementation. + Headers for the async winbind client library + Copyright (C) Volker Lendecke 2008 + + ** NOTE! The following LGPL license applies to the wbclient + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 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 Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef _WBC_ASYNC_H_ +#define _WBC_ASYNC_H_ + +#include +#include +#include "nsswitch/libwbclient/wbclient.h" + +struct wb_context; +struct winbindd_request; +struct winbindd_response; + +struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, bool need_priv, + struct winbindd_request *wb_req); +wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct winbindd_response **presponse); +struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx); + +/* Definitions from wb_reqtrans.c */ +wbcErr map_wbc_err_from_errno(int error); + +bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err); +wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req); + +struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t max_extra_data); +ssize_t wb_req_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct winbindd_request **preq, int *err); + +struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_request *wb_req); +ssize_t wb_req_write_recv(struct tevent_req *req, int *err); + +struct tevent_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, int fd); +ssize_t wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct winbindd_response **presp, int *err); + +struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_response *wb_resp); +ssize_t wb_resp_write_recv(struct tevent_req *req, int *err); + +struct tevent_req *wb_simple_trans_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue, int fd, + struct winbindd_request *wb_req); +int wb_simple_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct winbindd_response **presponse, int *err); + +#endif /*_WBC_ASYNC_H_*/ diff --git a/nsswitch/libwbclient/wbclient.c b/nsswitch/libwbclient/wbclient.c index f5c72315f2..77b7e12d04 100644 --- a/nsswitch/libwbclient/wbclient.c +++ b/nsswitch/libwbclient/wbclient.c @@ -22,6 +22,8 @@ /* Required Headers */ +#include "lib/talloc/talloc.h" +#include "lib/tevent/tevent.h" #include "libwbclient.h" /* From wb_common.c */ diff --git a/nsswitch/libwbclient/wbclient_internal.h b/nsswitch/libwbclient/wbclient_internal.h index fc03c5409b..2d103ab3df 100644 --- a/nsswitch/libwbclient/wbclient_internal.h +++ b/nsswitch/libwbclient/wbclient_internal.h @@ -28,5 +28,4 @@ wbcErr wbcRequestResponse(int cmd, struct winbindd_request *request, struct winbindd_response *response); - #endif /* _WBCLIENT_INTERNAL_H */ diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h index 11b2069c3a..1785c30906 100644 --- a/nsswitch/winbind_struct_protocol.h +++ b/nsswitch/winbind_struct_protocol.h @@ -15,6 +15,11 @@ #define SAFE_FREE(x) do { if(x) {free(x); x=NULL;} } while(0) #endif +#ifndef FSTRING_LEN +#define FSTRING_LEN 256 +typedef char fstring[FSTRING_LEN]; +#endif + #ifndef _WINBINDD_NTDOM_H #define _WINBINDD_NTDOM_H diff --git a/source3/Makefile.in b/source3/Makefile.in index 72fce60faa..613e127770 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -992,7 +992,7 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \ $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ - lib/wb_reqtrans.o lib/wbclient.o \ + @LIBWBCLIENT_STATIC@ \ $(LIBNDR_GEN_OBJ0) MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ @@ -1876,7 +1876,10 @@ LIBWBCLIENT_OBJ0 = ../nsswitch/libwbclient/wbclient.o \ ../nsswitch/libwbclient/wbc_idmap.o \ ../nsswitch/libwbclient/wbc_sid.o \ ../nsswitch/libwbclient/wbc_guid.o \ - ../nsswitch/libwbclient/wbc_pam.o + ../nsswitch/libwbclient/wbc_pam.o \ + ../nsswitch/libwbclient/wb_reqtrans.o \ + ../nsswitch/libwbclient/wbc_async.o + LIBWBCLIENT_OBJ = $(LIBWBCLIENT_OBJ0) \ $(WBCOMMON_OBJ) \ $(LIBREPLACE_OBJ) @@ -1887,7 +1890,8 @@ LIBWBCLIENT_SHARED_TARGET_SONAME=$(LIBWBCLIENT_SHARED_TARGET).$(LIBWBCLIENT_SOVE LIBWBCLIENT_STATIC_TARGET=@LIBWBCLIENT_STATIC_TARGET@ LIBWBCLIENT=@LIBWBCLIENT_STATIC@ @LIBWBCLIENT_SHARED@ LIBWBCLIENT_SYMS=$(srcdir)/exports/libwbclient.@SYMSEXT@ -LIBWBCLIENT_HEADERS=$(srcdir)/../nsswitch/libwbclient/wbclient.h +LIBWBCLIENT_HEADERS=$(srcdir)/../nsswitch/libwbclient/wbclient.h \ + $(srcdir)/../nsswitch/libwbclient/wbc_async.h $(LIBWBCLIENT_SYMS): $(LIBWBCLIENT_HEADERS) @$(MKSYMS_SH) $(AWK) $@ $(LIBWBCLIENT_HEADERS) diff --git a/source3/include/wbc_async.h b/source3/include/wbc_async.h deleted file mode 100644 index 96c5f8c348..0000000000 --- a/source3/include/wbc_async.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Headers for the async winbind client library - Copyright (C) Volker Lendecke 2008 - - ** NOTE! The following LGPL license applies to the wbclient - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 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 Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef _WBC_ASYNC_H_ -#define _WBC_ASYNC_H_ - -#include "nsswitch/libwbclient/wbclient.h" - -struct wb_context; - -struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct wb_context *wb_ctx, bool need_priv, - struct winbindd_request *wb_req); -wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct winbindd_response **presponse); -struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx); - -/* Definitions from wb_reqtrans.c */ -wbcErr map_wbc_err_from_errno(int error); - -bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err); -wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req); - -struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, size_t max_extra_data); -ssize_t wb_req_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct winbindd_request **preq, int *err); - -struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tevent_queue *queue, int fd, - struct winbindd_request *wb_req); -ssize_t wb_req_write_recv(struct tevent_req *req, int *err); - -struct tevent_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd); -ssize_t wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct winbindd_response **presp, int *err); - -struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tevent_queue *queue, int fd, - struct winbindd_response *wb_resp); -ssize_t wb_resp_write_recv(struct tevent_req *req, int *err); - -struct tevent_req *wb_simple_trans_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tevent_queue *queue, int fd, - struct winbindd_request *wb_req); -int wb_simple_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct winbindd_response **presponse, int *err); - -#endif /*_WBC_ASYNC_H_*/ diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c deleted file mode 100644 index 7088925927..0000000000 --- a/source3/lib/wb_reqtrans.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Async transfer of winbindd_request and _response structs - - Copyright (C) Volker Lendecke 2008 - - ** NOTE! The following LGPL license applies to the wbclient - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 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 Lesser General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "wbc_async.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_WINBIND - -struct req_read_state { - struct winbindd_request *wb_req; - size_t max_extra_data; - ssize_t ret; -}; - -static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data); -static void wb_req_read_done(struct tevent_req *subreq); - -struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, size_t max_extra_data) -{ - struct tevent_req *req, *subreq; - struct req_read_state *state; - - req = tevent_req_create(mem_ctx, &state, struct req_read_state); - if (req == NULL) { - return NULL; - } - state->max_extra_data = max_extra_data; - - subreq = read_packet_send(state, ev, fd, 4, wb_req_more, state); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, wb_req_read_done, req); - return req; -} - -static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data) -{ - struct req_read_state *state = talloc_get_type_abort( - private_data, struct req_read_state); - struct winbindd_request *req = (struct winbindd_request *)buf; - - if (buflen == 4) { - if (req->length != sizeof(struct winbindd_request)) { - DEBUG(0, ("wb_req_read_len: Invalid request size " - "received: %d (expected %d)\n", - (int)req->length, - (int)sizeof(struct winbindd_request))); - return -1; - } - return sizeof(struct winbindd_request) - 4; - } - - if ((state->max_extra_data != 0) - && (req->extra_len > state->max_extra_data)) { - DEBUG(3, ("Got request with %d bytes extra data on " - "unprivileged socket\n", (int)req->extra_len)); - return -1; - } - - return req->extra_len; -} - -static void wb_req_read_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct req_read_state *state = tevent_req_data( - req, struct req_read_state); - int err; - uint8_t *buf; - - state->ret = read_packet_recv(subreq, state, &buf, &err); - TALLOC_FREE(subreq); - if (state->ret == -1) { - tevent_req_error(req, err); - return; - } - - state->wb_req = (struct winbindd_request *)buf; - - if (state->wb_req->extra_len != 0) { - state->wb_req->extra_data.data = - (char *)buf + sizeof(struct winbindd_request); - } else { - state->wb_req->extra_data.data = NULL; - } - tevent_req_done(req); -} - -ssize_t wb_req_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct winbindd_request **preq, int *err) -{ - struct req_read_state *state = tevent_req_data( - req, struct req_read_state); - - if (tevent_req_is_unix_error(req, err)) { - return -1; - } - *preq = talloc_move(mem_ctx, &state->wb_req); - return state->ret; -} - -struct req_write_state { - struct iovec iov[2]; - ssize_t ret; -}; - -static void wb_req_write_done(struct tevent_req *subreq); - -struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tevent_queue *queue, int fd, - struct winbindd_request *wb_req) -{ - struct tevent_req *req, *subreq; - struct req_write_state *state; - int count = 1; - - req = tevent_req_create(mem_ctx, &state, struct req_write_state); - if (req == NULL) { - return NULL; - } - - state->iov[0].iov_base = (void *)wb_req; - state->iov[0].iov_len = sizeof(struct winbindd_request); - - if (wb_req->extra_len != 0) { - state->iov[1].iov_base = (void *)wb_req->extra_data.data; - state->iov[1].iov_len = wb_req->extra_len; - count = 2; - } - - subreq = writev_send(state, ev, queue, fd, true, state->iov, count); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, wb_req_write_done, req); - return req; -} - -static void wb_req_write_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct req_write_state *state = tevent_req_data( - req, struct req_write_state); - int err; - - state->ret = writev_recv(subreq, &err); - TALLOC_FREE(subreq); - if (state->ret < 0) { - tevent_req_error(req, err); - return; - } - tevent_req_done(req); -} - -ssize_t wb_req_write_recv(struct tevent_req *req, int *err) -{ - struct req_write_state *state = tevent_req_data( - req, struct req_write_state); - - if (tevent_req_is_unix_error(req, err)) { - return -1; - } - return state->ret; -} - -struct resp_read_state { - struct winbindd_response *wb_resp; - ssize_t ret; -}; - -static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data); -static void wb_resp_read_done(struct tevent_req *subreq); - -struct tevent_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, int fd) -{ - struct tevent_req *req, *subreq; - struct resp_read_state *state; - - req = tevent_req_create(mem_ctx, &state, struct resp_read_state); - if (req == NULL) { - return NULL; - } - - subreq = read_packet_send(state, ev, fd, 4, wb_resp_more, state); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, wb_resp_read_done, req); - return req; -} - -static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data) -{ - struct winbindd_response *resp = (struct winbindd_response *)buf; - - if (buflen == 4) { - if (resp->length < sizeof(struct winbindd_response)) { - DEBUG(0, ("wb_resp_read_len: Invalid response size " - "received: %d (expected at least%d)\n", - (int)resp->length, - (int)sizeof(struct winbindd_response))); - return -1; - } - } - return resp->length - buflen; -} - -static void wb_resp_read_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct resp_read_state *state = tevent_req_data( - req, struct resp_read_state); - uint8_t *buf; - int err; - - state->ret = read_packet_recv(subreq, state, &buf, &err); - TALLOC_FREE(subreq); - if (state->ret == -1) { - tevent_req_error(req, err); - return; - } - - state->wb_resp = (struct winbindd_response *)buf; - - if (state->wb_resp->length > sizeof(struct winbindd_response)) { - state->wb_resp->extra_data.data = - (char *)buf + sizeof(struct winbindd_response); - } else { - state->wb_resp->extra_data.data = NULL; - } - tevent_req_done(req); -} - -ssize_t wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct winbindd_response **presp, int *err) -{ - struct resp_read_state *state = tevent_req_data( - req, struct resp_read_state); - - if (tevent_req_is_unix_error(req, err)) { - return -1; - } - *presp = talloc_move(mem_ctx, &state->wb_resp); - return state->ret; -} - -struct resp_write_state { - struct iovec iov[2]; - ssize_t ret; -}; - -static void wb_resp_write_done(struct tevent_req *subreq); - -struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tevent_queue *queue, int fd, - struct winbindd_response *wb_resp) -{ - struct tevent_req *req, *subreq; - struct resp_write_state *state; - int count = 1; - - req = tevent_req_create(mem_ctx, &state, struct resp_write_state); - if (req == NULL) { - return NULL; - } - - state->iov[0].iov_base = (void *)wb_resp; - state->iov[0].iov_len = sizeof(struct winbindd_response); - - if (wb_resp->length > sizeof(struct winbindd_response)) { - state->iov[1].iov_base = (void *)wb_resp->extra_data.data; - state->iov[1].iov_len = - wb_resp->length - sizeof(struct winbindd_response); - count = 2; - } - - subreq = writev_send(state, ev, queue, fd, true, state->iov, count); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, wb_resp_write_done, req); - return req; -} - -static void wb_resp_write_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct resp_write_state *state = tevent_req_data( - req, struct resp_write_state); - int err; - - state->ret = writev_recv(subreq, &err); - TALLOC_FREE(subreq); - if (state->ret < 0) { - tevent_req_error(req, err); - return; - } - tevent_req_done(req); -} - -ssize_t wb_resp_write_recv(struct tevent_req *req, int *err) -{ - struct resp_write_state *state = tevent_req_data( - req, struct resp_write_state); - - if (tevent_req_is_unix_error(req, err)) { - return -1; - } - return state->ret; -} - -struct wb_simple_trans_state { - struct tevent_context *ev; - int fd; - struct winbindd_response *wb_resp; -}; - -static void wb_simple_trans_write_done(struct tevent_req *subreq); -static void wb_simple_trans_read_done(struct tevent_req *subreq); - -struct tevent_req *wb_simple_trans_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tevent_queue *queue, int fd, - struct winbindd_request *wb_req) -{ - struct tevent_req *req, *subreq; - struct wb_simple_trans_state *state; - - req = tevent_req_create(mem_ctx, &state, struct wb_simple_trans_state); - if (req == NULL) { - return NULL; - } - - wb_req->length = sizeof(struct winbindd_request); - - state->ev = ev; - state->fd = fd; - - subreq = wb_req_write_send(state, ev, queue, fd, wb_req); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, wb_simple_trans_write_done, req); - - return req; -} - -static void wb_simple_trans_write_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_simple_trans_state *state = tevent_req_data( - req, struct wb_simple_trans_state); - ssize_t ret; - int err; - - ret = wb_req_write_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret == -1) { - tevent_req_error(req, err); - return; - } - subreq = wb_resp_read_send(state, state->ev, state->fd); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, wb_simple_trans_read_done, req); -} - -static void wb_simple_trans_read_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_simple_trans_state *state = tevent_req_data( - req, struct wb_simple_trans_state); - ssize_t ret; - int err; - - ret = wb_resp_read_recv(subreq, state, &state->wb_resp, &err); - TALLOC_FREE(subreq); - if (ret == -1) { - tevent_req_error(req, err); - return; - } - - tevent_req_done(req); -} - -int wb_simple_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct winbindd_response **presponse, int *err) -{ - struct wb_simple_trans_state *state = tevent_req_data( - req, struct wb_simple_trans_state); - - if (tevent_req_is_unix_error(req, err)) { - return -1; - } - *presponse = talloc_move(mem_ctx, &state->wb_resp); - return 0; -} diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c deleted file mode 100644 index d0070ea349..0000000000 --- a/source3/lib/wbclient.c +++ /dev/null @@ -1,678 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Infrastructure for async winbind requests - Copyright (C) Volker Lendecke 2008 - - ** NOTE! The following LGPL license applies to the wbclient - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 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 Lesser General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "wbc_async.h" - -wbcErr map_wbc_err_from_errno(int error) -{ - switch(error) { - case EPERM: - case EACCES: - return WBC_ERR_AUTH_ERROR; - case ENOMEM: - return WBC_ERR_NO_MEMORY; - case EIO: - default: - return WBC_ERR_UNKNOWN_FAILURE; - } -} - -bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err) -{ - enum tevent_req_state state; - uint64_t error; - if (!tevent_req_is_error(req, &state, &error)) { - *pwbc_err = WBC_ERR_SUCCESS; - return false; - } - - switch (state) { - case TEVENT_REQ_USER_ERROR: - *pwbc_err = error; - break; - case TEVENT_REQ_TIMED_OUT: - *pwbc_err = WBC_ERR_UNKNOWN_FAILURE; - break; - case TEVENT_REQ_NO_MEMORY: - *pwbc_err = WBC_ERR_NO_MEMORY; - break; - default: - *pwbc_err = WBC_ERR_UNKNOWN_FAILURE; - break; - } - return true; -} - -wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req) -{ - wbcErr wbc_err; - - if (tevent_req_is_wbcerr(req, &wbc_err)) { - return wbc_err; - } - - return WBC_ERR_SUCCESS; -} - -struct wb_context { - struct tevent_queue *queue; - int fd; - bool is_priv; -}; - -static int make_nonstd_fd(int fd) -{ - int i; - int sys_errno = 0; - int fds[3]; - int num_fds = 0; - - if (fd == -1) { - return -1; - } - while (fd < 3) { - fds[num_fds++] = fd; - fd = dup(fd); - if (fd == -1) { - sys_errno = errno; - break; - } - } - for (i=0; i= 0) { - flags |= FD_CLOEXEC; - result = fcntl( new_fd, F_SETFD, flags ); - } - if (result < 0) { - goto fail; - } -#endif - return new_fd; - - fail: - if (new_fd != -1) { - int sys_errno = errno; - close(new_fd); - errno = sys_errno; - } - return -1; -} - -struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx) -{ - struct wb_context *result; - - result = talloc(mem_ctx, struct wb_context); - if (result == NULL) { - return NULL; - } - result->queue = tevent_queue_create(result, "wb_trans"); - if (result->queue == NULL) { - TALLOC_FREE(result); - return NULL; - } - result->fd = -1; - result->is_priv = false; - return result; -} - -struct wb_connect_state { - int dummy; -}; - -static void wbc_connect_connected(struct tevent_req *subreq); - -static struct tevent_req *wb_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct wb_context *wb_ctx, - const char *dir) -{ - struct tevent_req *result, *subreq; - struct wb_connect_state *state; - struct sockaddr_un sunaddr; - struct stat st; - char *path = NULL; - wbcErr wbc_err; - - result = tevent_req_create(mem_ctx, &state, struct wb_connect_state); - if (result == NULL) { - return NULL; - } - - if (wb_ctx->fd != -1) { - close(wb_ctx->fd); - wb_ctx->fd = -1; - } - - /* Check permissions on unix socket directory */ - - if (lstat(dir, &st) == -1) { - wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE; - goto post_status; - } - - if (!S_ISDIR(st.st_mode) || - (st.st_uid != 0 && st.st_uid != geteuid())) { - wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE; - goto post_status; - } - - /* Connect to socket */ - - path = talloc_asprintf(talloc_tos(), "%s/%s", dir, - WINBINDD_SOCKET_NAME); - if (path == NULL) { - goto nomem; - } - - sunaddr.sun_family = AF_UNIX; - strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)); - TALLOC_FREE(path); - - /* If socket file doesn't exist, don't bother trying to connect - with retry. This is an attempt to make the system usable when - the winbindd daemon is not running. */ - - if ((lstat(sunaddr.sun_path, &st) == -1) - || !S_ISSOCK(st.st_mode) - || (st.st_uid != 0 && st.st_uid != geteuid())) { - wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE; - goto post_status; - } - - wb_ctx->fd = make_safe_fd(socket(AF_UNIX, SOCK_STREAM, 0)); - if (wb_ctx->fd == -1) { - wbc_err = map_wbc_err_from_errno(errno); - goto post_status; - } - - subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd, - (struct sockaddr *)(void *)&sunaddr, - sizeof(sunaddr)); - if (subreq == NULL) { - goto nomem; - } - tevent_req_set_callback(subreq, wbc_connect_connected, result); - return result; - - post_status: - tevent_req_error(result, wbc_err); - return tevent_req_post(result, ev); - nomem: - TALLOC_FREE(result); - return NULL; -} - -static void wbc_connect_connected(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - int res, err; - - res = async_connect_recv(subreq, &err); - TALLOC_FREE(subreq); - if (res == -1) { - tevent_req_error(req, map_wbc_err_from_errno(err)); - return; - } - tevent_req_done(req); -} - -static wbcErr wb_connect_recv(struct tevent_req *req) -{ - return tevent_req_simple_recv_wbcerr(req); -} - -static const char *winbindd_socket_dir(void) -{ -#ifdef SOCKET_WRAPPER - const char *env_dir; - - env_dir = getenv(WINBINDD_SOCKET_DIR_ENVVAR); - if (env_dir) { - return env_dir; - } -#endif - - return WINBINDD_SOCKET_DIR; -} - -struct wb_open_pipe_state { - struct wb_context *wb_ctx; - struct tevent_context *ev; - bool need_priv; - struct winbindd_request wb_req; -}; - -static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq); -static void wb_open_pipe_ping_done(struct tevent_req *subreq); -static void wb_open_pipe_getpriv_done(struct tevent_req *subreq); -static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq); - -static struct tevent_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct wb_context *wb_ctx, - bool need_priv) -{ - struct tevent_req *result, *subreq; - struct wb_open_pipe_state *state; - - result = tevent_req_create(mem_ctx, &state, struct wb_open_pipe_state); - if (result == NULL) { - return NULL; - } - state->wb_ctx = wb_ctx; - state->ev = ev; - state->need_priv = need_priv; - - if (wb_ctx->fd != -1) { - close(wb_ctx->fd); - wb_ctx->fd = -1; - } - - subreq = wb_connect_send(state, ev, wb_ctx, winbindd_socket_dir()); - if (subreq == NULL) { - goto fail; - } - tevent_req_set_callback(subreq, wb_open_pipe_connect_nonpriv_done, - result); - return result; - - fail: - TALLOC_FREE(result); - return NULL; -} - -static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_open_pipe_state *state = tevent_req_data( - req, struct wb_open_pipe_state); - wbcErr wbc_err; - - wbc_err = wb_connect_recv(subreq); - TALLOC_FREE(subreq); - if (!WBC_ERROR_IS_OK(wbc_err)) { - state->wb_ctx->is_priv = true; - tevent_req_error(req, wbc_err); - return; - } - - ZERO_STRUCT(state->wb_req); - state->wb_req.cmd = WINBINDD_INTERFACE_VERSION; - state->wb_req.pid = getpid(); - - subreq = wb_simple_trans_send(state, state->ev, NULL, - state->wb_ctx->fd, &state->wb_req); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, wb_open_pipe_ping_done, req); -} - -static void wb_open_pipe_ping_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_open_pipe_state *state = tevent_req_data( - req, struct wb_open_pipe_state); - struct winbindd_response *wb_resp; - int ret, err; - - ret = wb_simple_trans_recv(subreq, state, &wb_resp, &err); - TALLOC_FREE(subreq); - if (ret == -1) { - tevent_req_error(req, map_wbc_err_from_errno(err)); - return; - } - - if (!state->need_priv) { - tevent_req_done(req); - return; - } - - state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR; - state->wb_req.pid = getpid(); - - subreq = wb_simple_trans_send(state, state->ev, NULL, - state->wb_ctx->fd, &state->wb_req); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, wb_open_pipe_getpriv_done, req); -} - -static void wb_open_pipe_getpriv_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_open_pipe_state *state = tevent_req_data( - req, struct wb_open_pipe_state); - struct winbindd_response *wb_resp = NULL; - int ret, err; - - ret = wb_simple_trans_recv(subreq, state, &wb_resp, &err); - TALLOC_FREE(subreq); - if (ret == -1) { - tevent_req_error(req, map_wbc_err_from_errno(err)); - return; - } - - close(state->wb_ctx->fd); - state->wb_ctx->fd = -1; - - subreq = wb_connect_send(state, state->ev, state->wb_ctx, - (char *)wb_resp->extra_data.data); - TALLOC_FREE(wb_resp); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, wb_open_pipe_connect_priv_done, req); -} - -static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_open_pipe_state *state = tevent_req_data( - req, struct wb_open_pipe_state); - wbcErr wbc_err; - - wbc_err = wb_connect_recv(subreq); - TALLOC_FREE(subreq); - if (!WBC_ERROR_IS_OK(wbc_err)) { - tevent_req_error(req, wbc_err); - return; - } - state->wb_ctx->is_priv = true; - tevent_req_done(req); -} - -static wbcErr wb_open_pipe_recv(struct tevent_req *req) -{ - return tevent_req_simple_recv_wbcerr(req); -} - -struct wb_trans_state { - struct wb_trans_state *prev, *next; - struct wb_context *wb_ctx; - struct tevent_context *ev; - struct winbindd_request *wb_req; - struct winbindd_response *wb_resp; - bool need_priv; -}; - -static bool closed_fd(int fd) -{ - struct timeval tv; - fd_set r_fds; - int selret; - - if (fd == -1) { - return true; - } - - FD_ZERO(&r_fds); - FD_SET(fd, &r_fds); - ZERO_STRUCT(tv); - - selret = select(fd+1, &r_fds, NULL, NULL, &tv); - if (selret == -1) { - return true; - } - if (selret == 0) { - return false; - } - return (FD_ISSET(fd, &r_fds)); -} - -static void wb_trans_trigger(struct tevent_req *req, void *private_data); -static void wb_trans_connect_done(struct tevent_req *subreq); -static void wb_trans_done(struct tevent_req *subreq); -static void wb_trans_retry_wait_done(struct tevent_req *subreq); - -struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct wb_context *wb_ctx, bool need_priv, - struct winbindd_request *wb_req) -{ - struct tevent_req *req; - struct wb_trans_state *state; - - req = tevent_req_create(mem_ctx, &state, struct wb_trans_state); - if (req == NULL) { - return NULL; - } - state->wb_ctx = wb_ctx; - state->ev = ev; - state->wb_req = wb_req; - state->need_priv = need_priv; - - if (!tevent_queue_add(wb_ctx->queue, ev, req, wb_trans_trigger, - NULL)) { - tevent_req_nomem(NULL, req); - return tevent_req_post(req, ev); - } - return req; -} - -static void wb_trans_trigger(struct tevent_req *req, void *private_data) -{ - struct wb_trans_state *state = tevent_req_data( - req, struct wb_trans_state); - struct tevent_req *subreq; - - if ((state->wb_ctx->fd != -1) && closed_fd(state->wb_ctx->fd)) { - close(state->wb_ctx->fd); - state->wb_ctx->fd = -1; - } - - if ((state->wb_ctx->fd == -1) - || (state->need_priv && !state->wb_ctx->is_priv)) { - subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx, - state->need_priv); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, wb_trans_connect_done, req); - return; - } - - state->wb_req->pid = getpid(); - - subreq = wb_simple_trans_send(state, state->ev, NULL, - state->wb_ctx->fd, state->wb_req); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, wb_trans_done, req); -} - -static bool wb_trans_retry(struct tevent_req *req, - struct wb_trans_state *state, - wbcErr wbc_err) -{ - struct tevent_req *subreq; - - if (WBC_ERROR_IS_OK(wbc_err)) { - return false; - } - - if (wbc_err == WBC_ERR_WINBIND_NOT_AVAILABLE) { - /* - * Winbind not around or we can't connect to the pipe. Fail - * immediately. - */ - tevent_req_error(req, wbc_err); - return true; - } - - /* - * The transfer as such failed, retry after one second - */ - - if (state->wb_ctx->fd != -1) { - close(state->wb_ctx->fd); - state->wb_ctx->fd = -1; - } - - subreq = tevent_wakeup_send(state, state->ev, - timeval_current_ofs(1, 0)); - if (tevent_req_nomem(subreq, req)) { - return true; - } - tevent_req_set_callback(subreq, wb_trans_retry_wait_done, req); - return true; -} - -static void wb_trans_retry_wait_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_trans_state *state = tevent_req_data( - req, struct wb_trans_state); - bool ret; - - ret = tevent_wakeup_recv(subreq); - TALLOC_FREE(subreq); - if (!ret) { - tevent_req_error(req, WBC_ERR_UNKNOWN_FAILURE); - return; - } - - subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx, - state->need_priv); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, wb_trans_connect_done, req); -} - -static void wb_trans_connect_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_trans_state *state = tevent_req_data( - req, struct wb_trans_state); - wbcErr wbc_err; - - wbc_err = wb_open_pipe_recv(subreq); - TALLOC_FREE(subreq); - - if (wb_trans_retry(req, state, wbc_err)) { - return; - } - - subreq = wb_simple_trans_send(state, state->ev, NULL, - state->wb_ctx->fd, state->wb_req); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, wb_trans_done, req); -} - -static void wb_trans_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_trans_state *state = tevent_req_data( - req, struct wb_trans_state); - int ret, err; - - ret = wb_simple_trans_recv(subreq, state, &state->wb_resp, &err); - TALLOC_FREE(subreq); - if ((ret == -1) - && wb_trans_retry(req, state, map_wbc_err_from_errno(err))) { - return; - } - - tevent_req_done(req); -} - -wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct winbindd_response **presponse) -{ - struct wb_trans_state *state = tevent_req_data( - req, struct wb_trans_state); - wbcErr wbc_err; - - if (tevent_req_is_wbcerr(req, &wbc_err)) { - return wbc_err; - } - - *presponse = talloc_move(mem_ctx, &state->wb_resp); - return WBC_ERR_SUCCESS; -} diff --git a/source3/samba4.mk b/source3/samba4.mk index 3f661bdd14..e63a8453c0 100644 --- a/source3/samba4.mk +++ b/source3/samba4.mk @@ -74,6 +74,7 @@ clustersrcdir := $(samba4srcdir)/cluster libnetsrcdir := $(samba4srcdir)/libnet authsrcdir := $(samba4srcdir)/auth nsswitchsrcdir := $(samba4srcdir)/../nsswitch +libwbclientsrcdir := $(nsswitchsrcdir)/libwbclient libsrcdir := $(samba4srcdir)/lib libsocketsrcdir := $(samba4srcdir)/lib/socket libcharsetsrcdir := $(samba4srcdir)/../lib/util/charset diff --git a/source3/torture/torture.c b/source3/torture/torture.c index cfd3d640f9..30e7e8cbc5 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -18,7 +18,7 @@ */ #include "includes.h" -#include "wbc_async.h" +#include "nsswitch/libwbclient/wbc_async.h" extern char *optarg; extern int optind; diff --git a/source4/Makefile b/source4/Makefile index 7bc48b9fe4..2a3ad2def1 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -58,6 +58,7 @@ clustersrcdir := cluster libnetsrcdir := libnet authsrcdir := auth nsswitchsrcdir := ../nsswitch +libwbclientsrcdir := ../nsswitch/libwbclient libsrcdir := lib libsocketsrcdir := lib/socket libcharsetsrcdir := ../lib/util/charset diff --git a/source4/libcli/wbclient/config.mk b/source4/libcli/wbclient/config.mk index 00df5dbb22..af4d3eff82 100644 --- a/source4/libcli/wbclient/config.mk +++ b/source4/libcli/wbclient/config.mk @@ -1,5 +1,5 @@ -[SUBSYSTEM::LIBWBCLIENT] +[SUBSYSTEM::LIBWBCLIENT_OLD] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS PRIVATE_DEPENDENCIES = NDR_WINBIND MESSAGING -LIBWBCLIENT_OBJ_FILES = $(libclisrcdir)/wbclient/wbclient.o +LIBWBCLIENT_OLD_OBJ_FILES = $(libclisrcdir)/wbclient/wbclient.o diff --git a/source4/main.mk b/source4/main.mk index 2e74ba9a5b..b4a82017c8 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -7,6 +7,7 @@ mkinclude smbd/process_model.mk mkinclude libnet/config.mk mkinclude auth/config.mk mkinclude ../nsswitch/config.mk +mkinclude ../nsswitch/libwbclient/config.mk mkinclude lib/samba3/config.mk mkinclude lib/socket/config.mk mkinclude ../lib/util/charset/config.mk diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 1d7949214a..1aaef3f1d4 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -42,7 +42,7 @@ OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init #PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING \ - LIBWBCLIENT pvfs_acl pvfs_aio + LIBWBCLIENT_OLD pvfs_acl pvfs_aio # End MODULE ntvfs_posix ################################################ diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk index dfc3d17bed..f3dc074125 100644 --- a/source4/rpc_server/config.mk +++ b/source4/rpc_server/config.mk @@ -85,7 +85,7 @@ PRIVATE_DEPENDENCIES = \ SAMDB \ NDR_UNIXINFO \ NSS_WRAPPER \ - LIBWBCLIENT + LIBWBCLIENT_OLD # End MODULE dcerpc_unixinfo ################################################ -- cgit From 29ee4f6a340dc4009c344983cd15bcb79aaf1163 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Wed, 1 Apr 2009 14:22:05 +0200 Subject: libwbclient: Silence a compiler warning --- nsswitch/libwbclient/wbc_pam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c index 61ce2a12d2..eeb798a78c 100644 --- a/nsswitch/libwbclient/wbc_pam.c +++ b/nsswitch/libwbclient/wbc_pam.c @@ -255,7 +255,7 @@ done: } static wbcErr wbc_create_logon_info(TALLOC_CTX *mem_ctx, - const struct winbindd_response *resp, + struct winbindd_response *resp, struct wbcLogonUserInfo **_i) { wbcErr wbc_status = WBC_ERR_SUCCESS; -- cgit From bb9103d9c4cb9d68c36f278ea31be9b8a12063b9 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Tue, 21 Apr 2009 09:58:42 +0200 Subject: libwbclient: Store the winbind socket dir to use in the wb_context --- nsswitch/libwbclient/wbc_async.c | 14 ++++++++++++-- nsswitch/libwbclient/wbc_async.h | 2 +- source3/torture/torture.c | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/nsswitch/libwbclient/wbc_async.c b/nsswitch/libwbclient/wbc_async.c index 141c9816aa..6a572f4203 100644 --- a/nsswitch/libwbclient/wbc_async.c +++ b/nsswitch/libwbclient/wbc_async.c @@ -88,6 +88,7 @@ struct wb_context { struct tevent_queue *queue; int fd; bool is_priv; + const char *dir; }; static int make_nonstd_fd(int fd) @@ -179,7 +180,10 @@ static int make_safe_fd(int fd) return -1; } -struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx) +/* Just put a prototype to avoid moving the whole function around */ +static const char *winbindd_socket_dir(void); + +struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx, const char* dir) { struct wb_context *result; @@ -194,6 +198,12 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx) } result->fd = -1; result->is_priv = false; + + if (dir != NULL) { + result->dir = dir; + } else { + result->dir = winbindd_socket_dir(); + } return result; } @@ -351,7 +361,7 @@ static struct tevent_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx, wb_ctx->fd = -1; } - subreq = wb_connect_send(state, ev, wb_ctx, winbindd_socket_dir()); + subreq = wb_connect_send(state, ev, wb_ctx, wb_ctx->dir); if (subreq == NULL) { goto fail; } diff --git a/nsswitch/libwbclient/wbc_async.h b/nsswitch/libwbclient/wbc_async.h index a2e0eed448..607dd9de28 100644 --- a/nsswitch/libwbclient/wbc_async.h +++ b/nsswitch/libwbclient/wbc_async.h @@ -38,7 +38,7 @@ struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct winbindd_request *wb_req); wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presponse); -struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx); +struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx, const char* dir); /* Definitions from wb_reqtrans.c */ wbcErr map_wbc_err_from_errno(int error); diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 30e7e8cbc5..d185a71727 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -5985,7 +5985,7 @@ static bool run_local_wbclient(int dummy) d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops); for (i=0; i Date: Sat, 30 May 2009 02:25:11 +0200 Subject: s3-selftest: Fix invalid /etc/group file used with nss_wrapper. Found by torture test. Guenther --- selftest/target/Samba3.pm | 1 + source3/script/tests/selftest.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 95d2a8253f..4723fd6909 100644 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -542,6 +542,7 @@ $unix_name:x:$unix_uid:$unix_gids[0]:$unix_name gecos:$prefix_abs:/bin/false open(GROUP, ">$nss_wrapper_group") or die("Unable to open $nss_wrapper_group"); print GROUP "nobody:x:65533: nogroup:x:65534:nobody +root:x:65532: $unix_name-group:x:$unix_gids[0]: "; close(GROUP); diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh index 956c5af77b..e3871132d2 100755 --- a/source3/script/tests/selftest.sh +++ b/source3/script/tests/selftest.sh @@ -289,6 +289,7 @@ EOF cat >$NSS_WRAPPER_GROUP< Date: Sat, 30 May 2009 09:49:17 +0200 Subject: Handle EINTR in async_sock.c --- lib/async_req/async_sock.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 09eec10fc5..d88edb177a 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -81,6 +81,10 @@ static void async_send_handler(struct tevent_context *ev, tevent_req_data(req, struct async_send_state); state->sent = send(state->fd, state->buf, state->len, state->flags); + if ((state->sent == -1) && (errno == EINTR)) { + /* retry */ + return; + } if (state->sent == -1) { tevent_req_error(req, errno); return; @@ -148,6 +152,10 @@ static void async_recv_handler(struct tevent_context *ev, state->received = recv(state->fd, state->buf, state->len, state->flags); + if ((state->received == -1) && (errno == EINTR)) { + /* retry */ + return; + } if (state->received == -1) { tevent_req_error(req, errno); return; @@ -427,6 +435,10 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, } written = writev(state->fd, state->iov, state->count); + if ((written == -1) && (errno = EINTR)) { + /* retry */ + return; + } if (written == -1) { tevent_req_error(req, errno); return; @@ -534,6 +546,10 @@ static void read_packet_handler(struct tevent_context *ev, nread = recv(state->fd, state->buf+state->nread, total-state->nread, 0); + if ((nread == -1) && (errno == EINTR)) { + /* retry */ + return; + } if (nread == -1) { tevent_req_error(req, errno); return; -- cgit From e9d1197b4ef79e23067a27ecace5843926b2bf26 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 30 May 2009 09:54:14 +0200 Subject: talloc_strdup "dir" in wb_context_init --- nsswitch/libwbclient/wbc_async.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nsswitch/libwbclient/wbc_async.c b/nsswitch/libwbclient/wbc_async.c index 6a572f4203..5f985f9d5a 100644 --- a/nsswitch/libwbclient/wbc_async.c +++ b/nsswitch/libwbclient/wbc_async.c @@ -200,10 +200,14 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx, const char* dir) result->is_priv = false; if (dir != NULL) { - result->dir = dir; + result->dir = talloc_strdup(result, dir); } else { result->dir = winbindd_socket_dir(); } + if (result->dir == NULL) { + TALLOC_FREE(result); + return NULL; + } return result; } -- cgit From 29d25d5ebfc5b0c76d066685de5cd12e8ebb6cda Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 30 May 2009 10:12:53 +0200 Subject: Move ads flags mapping to lib/ --- source3/Makefile.in | 1 + source3/lib/ads_flags.c | 150 +++++++++++++++++++++++++++++++++++++++++++++ source3/libads/ads_utils.c | 138 ++--------------------------------------- 3 files changed, 156 insertions(+), 133 deletions(-) create mode 100644 source3/lib/ads_flags.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 613e127770..9c87c6776a 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -372,6 +372,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/interface.o lib/pidfile.o \ lib/system.o lib/sendfile.o lib/recvfile.o lib/time.o \ lib/username.o \ + lib/ads_flags.o \ lib/util_pw.o lib/access.o lib/smbrun.o \ lib/bitmap.o lib/dprintf.o $(UTIL_REG_OBJ) \ lib/wins_srv.o \ diff --git a/source3/lib/ads_flags.c b/source3/lib/ads_flags.c new file mode 100644 index 0000000000..a8fa062f2a --- /dev/null +++ b/source3/lib/ads_flags.c @@ -0,0 +1,150 @@ +/* + Unix SMB/CIFS implementation. + ads (active directory) utility library + + Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Andrew Tridgell 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 3 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, see . +*/ + +#include "includes.h" + +/* +translated the ACB_CTRL Flags to UserFlags (userAccountControl) +*/ +uint32 ads_acb2uf(uint32 acb) +{ + uint32 uf = 0x00000000; + + if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE; + if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED; + if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD; + if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT; + if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT; + if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT; + if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT; + if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT; + if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT; + if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD; + if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT; + if (acb & ACB_USE_DES_KEY_ONLY) uf |= UF_USE_DES_KEY_ONLY; + if (acb & ACB_SMARTCARD_REQUIRED) uf |= UF_SMARTCARD_REQUIRED; + if (acb & ACB_TRUSTED_FOR_DELEGATION) uf |= UF_TRUSTED_FOR_DELEGATION; + if (acb & ACB_DONT_REQUIRE_PREAUTH) uf |= UF_DONT_REQUIRE_PREAUTH; + if (acb & ACB_NO_AUTH_DATA_REQD) uf |= UF_NO_AUTH_DATA_REQUIRED; + if (acb & ACB_NOT_DELEGATED) uf |= UF_NOT_DELEGATED; + if (acb & ACB_ENC_TXT_PWD_ALLOWED) uf |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED; + + return uf; +} + +/* +translated the UserFlags (userAccountControl) to ACB_CTRL Flags +*/ +uint32 ads_uf2acb(uint32 uf) +{ + uint32 acb = 0x00000000; + + if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED; + if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ; + if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ; + if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS; + if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP; + if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK; + if (uf & UF_USE_DES_KEY_ONLY) acb |= ACB_USE_DES_KEY_ONLY; + if (uf & UF_SMARTCARD_REQUIRED) acb |= ACB_SMARTCARD_REQUIRED; + if (uf & UF_TRUSTED_FOR_DELEGATION) acb |= ACB_TRUSTED_FOR_DELEGATION; + if (uf & UF_DONT_REQUIRE_PREAUTH) acb |= ACB_DONT_REQUIRE_PREAUTH; + if (uf & UF_NO_AUTH_DATA_REQUIRED) acb |= ACB_NO_AUTH_DATA_REQD; + if (uf & UF_NOT_DELEGATED) acb |= ACB_NOT_DELEGATED; + if (uf & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED) acb |= ACB_ENC_TXT_PWD_ALLOWED; + + switch (uf & UF_ACCOUNT_TYPE_MASK) + { + case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break; + case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break; + case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break; + case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break; + case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break; + /*Fix Me: what should we do here? */ + default: acb |= ACB_NORMAL;break; + } + + return acb; +} + +/* +get the accountType from the UserFlags +*/ +uint32 ads_uf2atype(uint32 uf) +{ + uint32 atype = 0x00000000; + + if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT; + else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT; + else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST; + else if (uf & UF_WORKSTATION_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST; + else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST; + + return atype; +} + +/* +get the accountType from the groupType +*/ +uint32 ads_gtype2atype(uint32 gtype) +{ + uint32 atype = 0x00000000; + + switch(gtype) { + case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: + atype = ATYPE_SECURITY_LOCAL_GROUP; + break; + case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: + atype = ATYPE_SECURITY_LOCAL_GROUP; + break; + case GTYPE_SECURITY_GLOBAL_GROUP: + atype = ATYPE_SECURITY_GLOBAL_GROUP; + break; + + case GTYPE_DISTRIBUTION_GLOBAL_GROUP: + atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP; + break; + case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP: + atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP; + break; + case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP: + atype = ATYPE_DISTRIBUTION_LOCAL_GROUP; + break; + } + + return atype; +} + +/* turn a sAMAccountType into a SID_NAME_USE */ +enum lsa_SidType ads_atype_map(uint32 atype) +{ + switch (atype & 0xF0000000) { + case ATYPE_GLOBAL_GROUP: + return SID_NAME_DOM_GRP; + case ATYPE_SECURITY_LOCAL_GROUP: + return SID_NAME_ALIAS; + case ATYPE_ACCOUNT: + return SID_NAME_USER; + default: + DEBUG(1,("hmm, need to map account type 0x%x\n", atype)); + } + return SID_NAME_UNKNOWN; +} diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index fc2ea9d9fd..213242c223 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -1,154 +1,26 @@ -/* +/* Unix SMB/CIFS implementation. ads (active directory) utility library - + Copyright (C) Stefan (metze) Metzmacher 2002 Copyright (C) Andrew Tridgell 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 3 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, see . */ #include "includes.h" -/* -translated the ACB_CTRL Flags to UserFlags (userAccountControl) -*/ -uint32 ads_acb2uf(uint32 acb) -{ - uint32 uf = 0x00000000; - - if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE; - if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED; - if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD; - if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT; - if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT; - if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT; - if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT; - if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT; - if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT; - if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD; - if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT; - if (acb & ACB_USE_DES_KEY_ONLY) uf |= UF_USE_DES_KEY_ONLY; - if (acb & ACB_SMARTCARD_REQUIRED) uf |= UF_SMARTCARD_REQUIRED; - if (acb & ACB_TRUSTED_FOR_DELEGATION) uf |= UF_TRUSTED_FOR_DELEGATION; - if (acb & ACB_DONT_REQUIRE_PREAUTH) uf |= UF_DONT_REQUIRE_PREAUTH; - if (acb & ACB_NO_AUTH_DATA_REQD) uf |= UF_NO_AUTH_DATA_REQUIRED; - if (acb & ACB_NOT_DELEGATED) uf |= UF_NOT_DELEGATED; - if (acb & ACB_ENC_TXT_PWD_ALLOWED) uf |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED; - - return uf; -} - -/* -translated the UserFlags (userAccountControl) to ACB_CTRL Flags -*/ -uint32 ads_uf2acb(uint32 uf) -{ - uint32 acb = 0x00000000; - - if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED; - if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ; - if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ; - if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS; - if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP; - if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK; - if (uf & UF_USE_DES_KEY_ONLY) acb |= ACB_USE_DES_KEY_ONLY; - if (uf & UF_SMARTCARD_REQUIRED) acb |= ACB_SMARTCARD_REQUIRED; - if (uf & UF_TRUSTED_FOR_DELEGATION) acb |= ACB_TRUSTED_FOR_DELEGATION; - if (uf & UF_DONT_REQUIRE_PREAUTH) acb |= ACB_DONT_REQUIRE_PREAUTH; - if (uf & UF_NO_AUTH_DATA_REQUIRED) acb |= ACB_NO_AUTH_DATA_REQD; - if (uf & UF_NOT_DELEGATED) acb |= ACB_NOT_DELEGATED; - if (uf & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED) acb |= ACB_ENC_TXT_PWD_ALLOWED; - - switch (uf & UF_ACCOUNT_TYPE_MASK) - { - case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break; - case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break; - case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break; - case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break; - case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break; - /*Fix Me: what should we do here? */ - default: acb |= ACB_NORMAL;break; - } - - return acb; -} - -/* -get the accountType from the UserFlags -*/ -uint32 ads_uf2atype(uint32 uf) -{ - uint32 atype = 0x00000000; - - if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT; - else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT; - else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST; - else if (uf & UF_WORKSTATION_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST; - else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST; - - return atype; -} - -/* -get the accountType from the groupType -*/ -uint32 ads_gtype2atype(uint32 gtype) -{ - uint32 atype = 0x00000000; - - switch(gtype) { - case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: - atype = ATYPE_SECURITY_LOCAL_GROUP; - break; - case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: - atype = ATYPE_SECURITY_LOCAL_GROUP; - break; - case GTYPE_SECURITY_GLOBAL_GROUP: - atype = ATYPE_SECURITY_GLOBAL_GROUP; - break; - - case GTYPE_DISTRIBUTION_GLOBAL_GROUP: - atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP; - break; - case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP: - atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP; - break; - case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP: - atype = ATYPE_DISTRIBUTION_LOCAL_GROUP; - break; - } - - return atype; -} - -/* turn a sAMAccountType into a SID_NAME_USE */ -enum lsa_SidType ads_atype_map(uint32 atype) -{ - switch (atype & 0xF0000000) { - case ATYPE_GLOBAL_GROUP: - return SID_NAME_DOM_GRP; - case ATYPE_SECURITY_LOCAL_GROUP: - return SID_NAME_ALIAS; - case ATYPE_ACCOUNT: - return SID_NAME_USER; - default: - DEBUG(1,("hmm, need to map account type 0x%x\n", atype)); - } - return SID_NAME_UNKNOWN; -} - const char *ads_get_ldap_server_name(ADS_STRUCT *ads) { return ads->config.ldap_server_name; -- cgit From 34c2172ae83d30f2d4e20baab8e3d3676179110f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 30 May 2009 11:30:16 +0200 Subject: Simplify the dropbox patch --- source3/smbd/filename.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index bcd8560ad9..059dca29c8 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -513,8 +513,14 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, goto fail; } - /* ENOENT is the only valid error here. */ - if ((errno != 0) && (errno != ENOENT)) { + /* + * ENOENT/EACCESS are the only valid errors + * here. EACCESS needs handling here for + * "dropboxes", i.e. directories where users + * can only put stuff with permission -wx. + */ + if ((errno != 0) && (errno != ENOENT) + && (errno != EACCES)) { /* * ENOTDIR and ELOOP both map to * NT_STATUS_OBJECT_PATH_NOT_FOUND @@ -524,12 +530,11 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, errno == ELOOP) { result = NT_STATUS_OBJECT_PATH_NOT_FOUND; - goto fail; - } else if (errno != EACCES) { + } else { result = map_nt_error_from_unix(errno); - goto fail; } + goto fail; } /* -- cgit From 29ae49240c1f358053133e8e52a961c5dca78f6f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 30 May 2009 09:48:38 -0400 Subject: Remove trailing whitespaces --- source3/utils/pdbedit.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 17175eb080..d288df9cc0 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -1,21 +1,21 @@ -/* +/* Unix SMB/CIFS implementation. passdb editing frontend - - Copyright (C) Simo Sorce 2000 - Copyright (C) Andrew Bartlett 2001 + + Copyright (C) Simo Sorce 2000-2009 + Copyright (C) Andrew Bartlett 2001 Copyright (C) Jelmer Vernooij 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 3 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, see . */ @@ -58,9 +58,9 @@ Add all currently available users to another db ********************************************************/ -static int export_database (struct pdb_methods *in, - struct pdb_methods *out, - const char *username) +static int export_database (struct pdb_methods *in, + struct pdb_methods *out, + const char *username) { NTSTATUS status; struct pdb_search *u_search; @@ -149,13 +149,13 @@ static int export_database (struct pdb_methods *in, Add all currently available group mappings to another db ********************************************************/ -static int export_groups (struct pdb_methods *in, struct pdb_methods *out) +static int export_groups (struct pdb_methods *in, struct pdb_methods *out) { GROUP_MAP *maps = NULL; size_t i, entries = 0; NTSTATUS status; - status = in->enum_group_mapping(in, get_global_sam_sid(), + status = in->enum_group_mapping(in, get_global_sam_sid(), SID_NAME_DOM_GRP, &maps, &entries, False); if ( NT_STATUS_IS_ERR(status) ) { @@ -176,7 +176,7 @@ static int export_groups (struct pdb_methods *in, struct pdb_methods *out) Reset account policies to their default values and remove marker ********************************************************/ -static int reinit_account_policies (void) +static int reinit_account_policies (void) { int i; @@ -261,31 +261,31 @@ static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdst printf ("Munged dial: %s\n", pdb_get_munged_dial(sam_pwent)); tmp = pdb_get_logon_time(sam_pwent); - printf ("Logon time: %s\n", + printf ("Logon time: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_logoff_time(sam_pwent); - printf ("Logoff time: %s\n", + printf ("Logoff time: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_kickoff_time(sam_pwent); - printf ("Kickoff time: %s\n", + printf ("Kickoff time: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_pass_last_set_time(sam_pwent); - printf ("Password last set: %s\n", + printf ("Password last set: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_pass_can_change_time(sam_pwent); - printf ("Password can change: %s\n", + printf ("Password can change: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_pass_must_change_time(sam_pwent); - printf ("Password must change: %s\n", + printf ("Password must change: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_bad_password_time(sam_pwent); - printf ("Last bad password : %s\n", + printf ("Last bad password : %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); printf ("Bad password count : %d\n", pdb_get_bad_password_count(sam_pwent)); @@ -311,7 +311,7 @@ static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdst (uint32)convert_time_t_to_uint32(pdb_get_pass_last_set_time(sam_pwent))); } else { uid = nametouid(pdb_get_username(sam_pwent)); - printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid, + printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid, pdb_get_fullname(sam_pwent)); } -- cgit From 9fc13f6a2d02c22f639a1a819e09ebb648faaff7 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 30 May 2009 10:16:31 -0400 Subject: Make it possible to change machine account sids Fixes bug #6081 --- source3/utils/pdbedit.c | 211 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 171 insertions(+), 40 deletions(-) diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index d288df9cc0..23c4e71e0d 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -53,6 +53,25 @@ #define MASK_ALWAYS_GOOD 0x0000001F #define MASK_USER_GOOD 0x00405FE0 +static int get_sid_from_cli_string(DOM_SID *sid, const char *str_sid) +{ + uint32_t rid; + + if (!string_to_sid(sid, str_sid)) { + /* not a complete sid, may be a RID, + * try building a SID */ + + if (sscanf(str_sid, "%u", &rid) != 1) { + fprintf(stderr, "Error passed string is not " + "a complete SID or RID!\n"); + return -1; + } + sid_copy(sid, get_global_sam_sid()); + sid_append_rid(sid, rid); + } + + return 0; +} /********************************************************* Add all currently available users to another db @@ -484,7 +503,6 @@ static int set_user_info(const char *username, const char *fullname, uint32_t not_settable; uint32_t new_flags; DOM_SID u_sid; - int u_rid; bool ret; sam_pwent = samu_new(NULL); @@ -548,16 +566,9 @@ static int set_user_info(const char *username, const char *fullname, PDB_CHANGED); } if (user_sid) { - if (!string_to_sid(&u_sid, user_sid)) { - /* not a complete sid, may be a RID, - * try building a SID */ - - if (sscanf(user_sid, "%d", &u_rid) != 1) { - fprintf(stderr, "Error passed string is not a complete user SID or RID!\n"); - return -1; - } - sid_copy(&u_sid, get_global_sam_sid()); - sid_append_rid(&u_sid, u_rid); + if (get_sid_from_cli_string(&u_sid, user_sid)) { + fprintf(stderr, "Failed to parse SID\n"); + return -1; } pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED); } @@ -578,6 +589,93 @@ static int set_user_info(const char *username, const char *fullname, return 0; } +static int set_machine_info(const char *machinename, + const char *account_control, + const char *machine_sid) +{ + struct samu *sam_pwent = NULL; + TALLOC_CTX *tosctx; + uint32_t acb_flags; + uint32_t not_settable; + uint32_t new_flags; + DOM_SID m_sid; + char *name; + int len; + bool ret; + + len = strlen(machinename); + if (len == 0) { + fprintf(stderr, "No machine name given\n"); + return -1; + } + + tosctx = talloc_tos(); + if (!tosctx) { + fprintf(stderr, "Out of memory!\n"); + return -1; + } + + sam_pwent = samu_new(tosctx); + if (!sam_pwent) { + return 1; + } + + if (machinename[len-1] == '$') { + name = talloc_strdup(sam_pwent, machinename); + } else { + name = talloc_asprintf(sam_pwent, "%s$", machinename); + } + if (!name) { + fprintf(stderr, "Out of memory!\n"); + TALLOC_FREE(sam_pwent); + return -1; + } + + strlower_m(name); + + ret = pdb_getsampwnam(sam_pwent, name); + if (!ret) { + fprintf (stderr, "Username not found!\n"); + TALLOC_FREE(sam_pwent); + return -1; + } + + if (account_control) { + not_settable = ~(ACB_DISABLED); + + new_flags = pdb_decode_acct_ctrl(account_control); + + if (new_flags & not_settable) { + fprintf(stderr, "Can only set [D] flags\n"); + TALLOC_FREE(sam_pwent); + return -1; + } + + acb_flags = pdb_get_acct_ctrl(sam_pwent); + + pdb_set_acct_ctrl(sam_pwent, + (acb_flags & not_settable) | new_flags, + PDB_CHANGED); + } + if (machine_sid) { + if (get_sid_from_cli_string(&m_sid, machine_sid)) { + fprintf(stderr, "Failed to parse SID\n"); + return -1; + } + pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED); + } + + if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) { + print_user_info(name, True, False); + } else { + fprintf (stderr, "Unable to modify entry!\n"); + TALLOC_FREE(sam_pwent); + return -1; + } + TALLOC_FREE(sam_pwent); + return 0; +} + /********************************************************* Add New User **********************************************************/ @@ -588,11 +686,10 @@ static int new_user(const char *username, const char *fullname, { char *pwd1 = NULL, *pwd2 = NULL; char *err = NULL, *msg = NULL; - struct samu *sam_pwent; + struct samu *sam_pwent = NULL; TALLOC_CTX *tosctx; NTSTATUS status; DOM_SID u_sid; - int u_rid; int flags; int ret; @@ -602,19 +699,10 @@ static int new_user(const char *username, const char *fullname, return -1; } - if (user_sid) { - if (!string_to_sid(&u_sid, user_sid)) { - /* not a complete sid, may be a RID, - * try building a SID */ - - if (sscanf(user_sid, "%d", &u_rid) != 1) { - fprintf(stderr, "Error passed string is not a complete user SID or RID!\n"); - ret = -1; - goto done; - } - sid_copy(&u_sid, get_global_sam_sid()); - sid_append_rid(&u_sid, u_rid); + if (get_sid_from_cli_string(&u_sid, user_sid)) { + fprintf(stderr, "Failed to parse SID\n"); + return -1; } } @@ -680,7 +768,7 @@ done: SAFE_FREE(pwd2); SAFE_FREE(err); SAFE_FREE(msg); - TALLOC_FREE(tosctx); + TALLOC_FREE(sam_pwent); return ret; } @@ -688,11 +776,13 @@ done: Add New Machine **********************************************************/ -static int new_machine(const char *machinename) +static int new_machine(const char *machinename, char *machine_sid) { char *err = NULL, *msg = NULL; + struct samu *sam_pwent = NULL; TALLOC_CTX *tosctx; NTSTATUS status; + DOM_SID m_sid; char *compatpwd; char *name; int flags; @@ -711,6 +801,13 @@ static int new_machine(const char *machinename) return -1; } + if (machine_sid) { + if (get_sid_from_cli_string(&m_sid, machine_sid)) { + fprintf(stderr, "Failed to parse SID\n"); + return -1; + } + } + compatpwd = talloc_strdup(tosctx, machinename); if (!compatpwd) { fprintf(stderr, "Out of memory!\n"); @@ -734,17 +831,42 @@ static int new_machine(const char *machinename) status = local_password_change(name, flags, compatpwd, &err, &msg); - if (NT_STATUS_IS_OK(status)) { - print_user_info(name, True, False); - ret = 0; - } else { + if (!NT_STATUS_IS_OK(status)) { if (err) fprintf(stderr, "%s", err); ret = -1; } - TALLOC_FREE(tosctx); + sam_pwent = samu_new(tosctx); + if (!sam_pwent) { + fprintf(stderr, "Out of memory!\n"); + ret = -1; + goto done; + } + + if (!pdb_getsampwnam(sam_pwent, name)) { + fprintf(stderr, "Machine %s not found!\n", name); + ret = -1; + goto done; + } + + if (machine_sid) + pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED); + + status = pdb_update_sam_account(sam_pwent); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, + "Failed to modify entry for %s.!\n", name); + ret = -1; + goto done; + } + + print_user_info(name, True, False); + ret = 0; + +done: SAFE_FREE(err); SAFE_FREE(msg); + TALLOC_FREE(sam_pwent); return ret; } @@ -855,6 +977,7 @@ int main (int argc, char **argv) static char *account_control = NULL; static char *account_policy = NULL; static char *user_sid = NULL; + static char *machine_sid = NULL; static long int account_policy_value = 0; bool account_policy_value_set = False; static int badpw_reset = False; @@ -879,6 +1002,7 @@ int main (int argc, char **argv) {"profile", 'p', POPT_ARG_STRING, &profile_path, 0, "set profile path", NULL}, {"domain", 'I', POPT_ARG_STRING, &user_domain, 0, "set a users' domain", NULL}, {"user SID", 'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL}, + {"machine SID", 'M', POPT_ARG_STRING, &machine_sid, 0, "set machine 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}, @@ -945,6 +1069,7 @@ int main (int argc, char **argv) (list_users ? BIT_LIST : 0) + (force_initialised_password ? BIT_FIX_INIT : 0) + (user_sid ? BIT_USERSIDS : 0) + + (machine_sid ? BIT_USERSIDS : 0) + (modify_user ? BIT_MODIFY : 0) + (add_user ? BIT_CREATE : 0) + (delete_user ? BIT_DELETE : 0) + @@ -1120,7 +1245,7 @@ int main (int argc, char **argv) /* account creation operations */ if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) { if (checkparms & BIT_MACHINE) { - return new_machine(user_name); + return new_machine(user_name, machine_sid); } else { return new_user(user_name, full_name, home_dir, home_drive, @@ -1139,13 +1264,19 @@ int main (int argc, char **argv) } /* account modification operations */ - if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) { - return set_user_info(user_name, full_name, - home_dir, acct_desc, - home_drive, logon_script, - profile_path, account_control, - user_sid, user_domain, - badpw_reset, hours_reset); + if (!(checkparms & ~(BIT_MODIFY + BIT_USER + BIT_MACHINE))) { + if (checkparms & BIT_MACHINE) { + return set_machine_info(user_name, + account_control, + machine_sid); + } else { + return set_user_info(user_name, full_name, + home_dir, acct_desc, + home_drive, logon_script, + profile_path, account_control, + user_sid, user_domain, + badpw_reset, hours_reset); + } } } -- cgit From 68e3442922ff222a5753533561352dd3a11ac0d2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 30 May 2009 18:24:14 +0200 Subject: Move a comment where it belongs --- source4/rpc_server/samr/dcesrv_samr.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index ec60ac7a45..03acf97cab 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -1223,6 +1223,11 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL return NT_STATUS_INVALID_PARAMETER; } + /* + * Start a transaction, so we can query and do a subsequent atomic + * modify + */ + ret = ldb_transaction_start(d_state->sam_ctx); if (ret != 0) { DEBUG(0,("Failed to start a transaction for user creation: %s\n", @@ -1292,9 +1297,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "sAMAccountName", account_name); samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", obj_class); - - /* Start a transaction, so we can query and do a subsequent atomic modify */ - + /* create the user */ ret = ldb_add(d_state->sam_ctx, msg); switch (ret) { -- cgit From ff736dfcadbac8dd7e220eb1f10aa2dfeb1cf7e7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 30 May 2009 13:28:03 -0700 Subject: Fix bug #6421 - POSIX read-only open fails on read-only shares. The change to smbd/trans2.c opens up SETFILEINFO calls to POSIX_OPEN only. The change to first smbd/open.c closes 2 holes that would have been exposed by allowing POSIX_OPENS on readonly shares, and their ability to set arbitrary flags permutations. The O_CREAT -> O_CREAT|O_EXCL change removes an illegal combination (O_EXCL without O_CREAT) that previously was being passed down to the open syscall. Jeremy. --- source3/smbd/open.c | 6 +++--- source3/smbd/trans2.c | 14 +++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index c1b29f68f3..fdfa99953f 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -346,7 +346,7 @@ static NTSTATUS open_file(files_struct *fsp, if (!CAN_WRITE(conn)) { /* It's a read-only share - fail if we wanted to write. */ - if(accmode != O_RDONLY) { + if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) { DEBUG(3,("Permission denied opening %s\n", path)); return NT_STATUS_ACCESS_DENIED; } else if(flags & O_CREAT) { @@ -354,8 +354,8 @@ static NTSTATUS open_file(files_struct *fsp, O_CREAT doesn't create the file if we have write access into the directory. */ - flags &= ~O_CREAT; - local_flags &= ~O_CREAT; + flags &= ~(O_CREAT|O_EXCL); + local_flags &= ~(O_CREAT|O_EXCL); } } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 1d95c207ba..d11bf088e0 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -6870,16 +6870,20 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } } - if (!CAN_WRITE(conn)) { - reply_doserror(req, ERRSRV, ERRaccess); - return; - } - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } + if (!CAN_WRITE(conn)) { + /* Allow POSIX opens. The open path will deny + * any non-readonly opens. */ + if (info_level != SMB_POSIX_PATH_OPEN) { + reply_doserror(req, ERRSRV, ERRaccess); + return; + } + } + DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n", tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data)); -- cgit From 241db90c310cb930b857d0f8fd20b5428e8ebb68 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 30 May 2009 22:43:17 +0200 Subject: nss_wrapper: try to fix the build of nss_wrapper on solaris. Guenther --- lib/nss_wrapper/nss_wrapper.c | 5 +++++ lib/replace/system/config.m4 | 1 + 2 files changed, 6 insertions(+) diff --git a/lib/nss_wrapper/nss_wrapper.c b/lib/nss_wrapper/nss_wrapper.c index b62be61d12..d7f7b0ba56 100644 --- a/lib/nss_wrapper/nss_wrapper.c +++ b/lib/nss_wrapper/nss_wrapper.c @@ -68,6 +68,11 @@ #define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS #endif +/* not all systems have getgrouplist */ +#ifndef HAVE_GETGROUPLIST +#define getgrouplist(user, group, groups, ngroups) 0 +#endif + /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support * for now */ #define REWRITE_CALLS diff --git a/lib/replace/system/config.m4 b/lib/replace/system/config.m4 index 5c9b53d5c5..e2196586ad 100644 --- a/lib/replace/system/config.m4 +++ b/lib/replace/system/config.m4 @@ -116,6 +116,7 @@ AC_VERIFY_C_PROTOTYPE([struct group *getgrent_r(struct group *src, char *buf, si #include #include ]) +AC_CHECK_FUNCS(getgrouplist) # locale AC_CHECK_HEADERS(ctype.h locale.h) -- cgit From 3984b76498aebf593b0a0e94a54b22c4a8401da3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 31 May 2009 11:06:23 +0200 Subject: Fix a C++ warning --- lib/crypto/sha256.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/crypto/sha256.c b/lib/crypto/sha256.c index a2def25814..233abe23f8 100644 --- a/lib/crypto/sha256.c +++ b/lib/crypto/sha256.c @@ -189,7 +189,7 @@ struct x32{ void SHA256_Update (SHA256_CTX *m, const void *v, size_t len) { - const unsigned char *p = v; + const unsigned char *p = (const unsigned char *)v; size_t old_sz = m->sz[0]; size_t offset; -- cgit From 14c13620345dfd9f1e18761f103aa66138bf8907 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 31 May 2009 11:14:06 +0200 Subject: Fix some nonempty blank lines --- source3/include/smbldap.h | 8 ++-- source3/lib/smbldap.c | 102 +++++++++++++++++++-------------------- source3/libads/ldap.c | 119 +++++++++++++++++++++++----------------------- source3/passdb/pdb_ldap.c | 104 ++++++++++++++++++++-------------------- 4 files changed, 165 insertions(+), 168 deletions(-) diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 7135c0be79..8710e77f3d 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -2,20 +2,20 @@ Unix SMB/CIFS mplementation. LDAP protocol helper functions for SAMBA Copyright (C) Gerald Carter 2001-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 3 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, see . - + */ #ifndef _SMBLDAP_H diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index b3b5fa7582..4833b96c5f 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -6,20 +6,20 @@ Copyright (C) Shahms King 2001 Copyright (C) Andrew Bartlett 2002-2003 Copyright (C) Stefan (metze) Metzmacher 2002-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 3 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, see . - + */ #include "includes.h" @@ -217,13 +217,13 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key ) { int i = 0; - + while ( table[i].attrib != LDAP_ATTR_LIST_END ) { if ( table[i].attrib == key ) return table[i].name; i++; } - + return NULL; } @@ -236,7 +236,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { { const char **names; int i = 0; - + while ( table[i].attrib != LDAP_ATTR_LIST_END ) i++; i++; @@ -253,7 +253,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { i++; } names[i] = NULL; - + return names; } @@ -266,25 +266,25 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { int max_len) { char **values; - + if ( !attribute ) return False; - + value[0] = '\0'; if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) { DEBUG (10, ("smbldap_get_single_attribute: [%s] = []\n", attribute)); - + return False; } - + 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); return False; } - + ldap_value_free(values); #ifdef DEBUG_PASSWORDS DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute, value)); @@ -533,7 +533,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { for (; mods[i]->mod_values[j] != NULL; j++); } mods[i]->mod_values = SMB_REALLOC_ARRAY(mods[i]->mod_values, char *, j + 2); - + if (mods[i]->mod_values == NULL) { smb_panic("smbldap_set_mod: out of memory!"); /* notreached. */ @@ -543,8 +543,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { smb_panic("smbldap_set_mod: String conversion failure!"); /* notreached. */ } - - + mods[i]->mod_values[j] = SMB_STRDUP(utf8_value); TALLOC_FREE(utf8_value); SMB_ASSERT(mods[i]->mod_values[j] != NULL); @@ -580,9 +579,9 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { } /* all of our string attributes are case insensitive */ - + 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 same... */ @@ -601,7 +600,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { /* 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 */ - + DEBUG(10,("smbldap_make_mod: deleting attribute |%s| values |%s|\n", attribute, oldval)); smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval); } @@ -659,7 +658,7 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) { struct smbldap_state *tmp_ldap_state; struct smbldap_state_lookup *t; - + if ((tmp_ldap_state = smbldap_find_state(ld))) { SMB_ASSERT(tmp_ldap_state == smbldap_state); return; @@ -667,7 +666,7 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) t = SMB_XMALLOC_P(struct smbldap_state_lookup); ZERO_STRUCTP(t); - + DLIST_ADD_END(smbldap_state_lookup_list, t, struct smbldap_state_lookup *); t->ld = ld; t->smbldap_state = smbldap_state; @@ -682,11 +681,11 @@ int smb_ldap_start_tls(LDAP *ldap_struct, int version) #ifdef LDAP_OPT_X_TLS int rc; #endif - + if (lp_ldap_ssl() != LDAP_SSL_START_TLS) { return LDAP_SUCCESS; } - + #ifdef LDAP_OPT_X_TLS if (version != LDAP_VERSION3) { DEBUG(0, ("Need LDAPv3 for Start TLS\n")); @@ -716,9 +715,9 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri) int rc; DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri)); - + #ifdef HAVE_LDAP_INITIALIZE - + rc = ldap_initialize(ldap_struct, uri); if (rc) { DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc))); @@ -740,9 +739,9 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri) if ( strnequal( uri, "URL:", 4 ) ) { uri += 4; } - + sscanf(uri, "%10[^:]://%254[^:/]:%d", protocol, host, &port); - + if (port == 0) { if (strequal(protocol, "ldap")) { port = LDAP_PORT; @@ -752,12 +751,12 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri) DEBUG(0, ("unrecognised protocol (%s)!\n", protocol)); } } - + if ((*ldap_struct = ldap_init(host, port)) == NULL) { DEBUG(0, ("ldap_init failed !\n")); return LDAP_OPERATIONS_ERROR; } - + if (strequal(protocol, "ldaps")) { #ifdef LDAP_OPT_X_TLS int tls = LDAP_OPT_X_TLS_HARD; @@ -765,7 +764,7 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri) { DEBUG(0, ("Failed to setup a TLS session\n")); } - + DEBUG(3,("LDAPS option set...!\n")); #else DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n")); @@ -811,7 +810,7 @@ int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version) { int version; int rc; - + /* assume the worst */ *new_version = LDAP_VERSION2; @@ -831,7 +830,7 @@ int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version) if (rc) { return rc; } - + *new_version = LDAP_VERSION3; return LDAP_SUCCESS; } @@ -894,7 +893,7 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state) if (rc) { return rc; } - + DEBUG(2, ("smbldap_open_connection: connection opened\n")); return rc; } @@ -909,11 +908,11 @@ static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, int *methodp, int freeit, void *arg) { struct smbldap_state *ldap_state = arg; - + /** @TODO Should we be doing something to check what servers we rebind to? Could we get a referral to a machine that we don't want to give our username and password to? */ - + if (freeit) { SAFE_FREE(*whop); if (*credp) { @@ -942,7 +941,7 @@ static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, } GetTimeOfDay(&ldap_state->last_rebind); - + return 0; } #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ @@ -1017,7 +1016,6 @@ static int rebindproc (LDAP *ldap_struct, char **whop, char **credp, return rebindproc_with_state(ldap_struct, whop, credp, method, freeit, ldap_state); - } # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/ #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ @@ -1058,7 +1056,7 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_ /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite (OpenLDAP) doesnt' seem to support it */ - + DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n", ldap_state->uri, ldap_state->bind_dn)); @@ -1194,17 +1192,17 @@ static NTSTATUS smbldap_close(struct smbldap_state *ldap_state) { if (!ldap_state) return NT_STATUS_INVALID_PARAMETER; - + if (ldap_state->ldap_struct != NULL) { ldap_unbind(ldap_state->ldap_struct); ldap_state->ldap_struct = NULL; } smbldap_delete_state(ldap_state); - + DEBUG(5,("The connection to the LDAP server was closed\n")); /* maybe free the results here --metze */ - + return NT_STATUS_OK; } @@ -1298,7 +1296,7 @@ static int smbldap_search_ext(struct smbldap_state *ldap_state, size_t converted_size; SMB_ASSERT(ldap_state); - + DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], " "scope => [%d]\n", base, filter, scope)); @@ -1525,7 +1523,7 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at } } } - + TALLOC_FREE(utf8_dn); return rc; } @@ -1537,7 +1535,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs char *utf8_dn; time_t endtime = time(NULL)+lp_ldap_timeout(); size_t converted_size; - + SMB_ASSERT(ldap_state); DEBUG(5,("smbldap_add: dn => [%s]\n", dn )); @@ -1569,7 +1567,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs } } } - + TALLOC_FREE(utf8_dn); return rc; } @@ -1581,7 +1579,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn) char *utf8_dn; time_t endtime = time(NULL)+lp_ldap_timeout(); size_t converted_size; - + SMB_ASSERT(ldap_state); DEBUG(5,("smbldap_delete: dn => [%s]\n", dn )); @@ -1613,7 +1611,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn) } } } - + TALLOC_FREE(utf8_dn); return rc; } @@ -1626,7 +1624,7 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state, int rc = LDAP_SERVER_DOWN; int attempts = 0; time_t endtime = time(NULL)+lp_ldap_timeout(); - + if (!ldap_state) return (-1); @@ -1655,7 +1653,7 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state, } } } - + return rc; } @@ -1683,7 +1681,7 @@ static void smbldap_idle_fn(struct event_context *event_ctx, DEBUG(10,("ldap connection not connected...\n")); return; } - + if ((state->last_use+SMBLDAP_IDLE_TIME) > now.tv_sec) { DEBUG(10,("ldap connection not idle...\n")); @@ -1694,7 +1692,7 @@ static void smbldap_idle_fn(struct event_context *event_ctx, private_data); return; } - + DEBUG(7,("ldap connection idle...closing connection\n")); smbldap_close(state); } @@ -1706,7 +1704,7 @@ static void smbldap_idle_fn(struct event_context *event_ctx, void smbldap_free_struct(struct smbldap_state **ldap_state) { smbldap_close(*ldap_state); - + if ((*ldap_state)->bind_secret) { memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret)); } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3e5764a598..102fc83d0f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -6,17 +6,17 @@ Copyright (C) Jim McDonough 2002 Copyright (C) Guenther Deschner 2005 Copyright (C) Gerald Carter 2006 - + 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 3 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, see . */ @@ -198,7 +198,7 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc) if (!server || !*server) { return False; } - + DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", server, ads->server.realm)); @@ -209,7 +209,7 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc) } /* this copes with inet_ntoa brokenness */ - + srv = SMB_STRDUP(server); ZERO_STRUCT( cldap_reply ); @@ -411,7 +411,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) SAFE_FREE(sitename); return NT_STATUS_OK; } - + /* keep track of failures */ add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL ); } @@ -652,7 +652,7 @@ got_connection: #endif /* If the caller() requested no LDAP bind, then we are done */ - + if (ads->auth.flags & ADS_AUTH_NO_BIND) { status = ADS_SUCCESS; goto out; @@ -663,7 +663,7 @@ got_connection: status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto out; } - + /* Otherwise setup the TCP LDAP session */ ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, @@ -690,14 +690,14 @@ got_connection: } /* fill in the current time and offsets */ - + status = ads_current_time( ads ); if ( !ADS_ERR_OK(status) ) { goto out; } /* Now do the bind */ - + if (ads->auth.flags & ADS_AUTH_ANON_BIND) { status = ADS_ERROR(ldap_simple_bind_s(ads->ldap.ld, NULL, NULL)); goto out; @@ -781,7 +781,7 @@ static struct berval **ads_dup_values(TALLOC_CTX *ctx, { struct berval **values; int i; - + if (!in_vals) return NULL; for (i=0; in_vals[i]; i++) ; /* count values */ @@ -826,7 +826,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) char **values; int i; size_t converted_size; - + if (!in_vals) return NULL; for (i=0; in_vals[i]; i++) ; /* count values */ @@ -901,7 +901,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, goto done; } } - + /* Paged results only available on ldap v3 or later */ ldap_get_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (version < LDAP_VERSION3) { @@ -976,7 +976,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, handle them and paged results at the same time. Using them together results in the result record containing the server page control being removed from the result list (tridge/jmcd) - + leaving this in despite the control that says don't generate referrals, in case the server doesn't support it (jmcd) */ @@ -1031,7 +1031,7 @@ done: if (ext_bv) { ber_bvfree(ext_bv); } - + /* if/when we decide to utf8-encode attrs, take out this next line */ TALLOC_FREE(search_attrs); @@ -1159,7 +1159,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, &res, &count, &cookie); if (!ADS_ERR_OK(status)) break; - + ads_process_results(ads, res, fn, data_area); ads_msgfree(ads, res); } @@ -1347,7 +1347,7 @@ char *ads_parent_dn(const char *dn) DEBUG(1, ("asprintf failed!\n")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - + status = ads_search(ads, res, expr, attrs); SAFE_FREE(expr); return status; @@ -1362,12 +1362,12 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) { #define ADS_MODLIST_ALLOC_SIZE 10 LDAPMod **mods; - + if ((mods = TALLOC_ZERO_ARRAY(ctx, LDAPMod *, ADS_MODLIST_ALLOC_SIZE + 1))) /* -1 is safety to make sure we don't go over the end. need to reset it to NULL before doing ldap modify */ mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; - + return (ADS_MODLIST)mods; } @@ -1408,7 +1408,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; *mods = (ADS_MODLIST)modlist; } - + if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod))) return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = talloc_strdup(ctx, name); @@ -1541,7 +1541,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) DEBUG(1, ("ads_gen_add: push_utf8_talloc failed!")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - + /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ @@ -1567,7 +1567,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) DEBUG(1, ("ads_del_dn: push_utf8_talloc failed!")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - + ret = ldap_delete_s(ads->ldap.ld, utf8_dn); TALLOC_FREE(utf8_dn); return ADS_ERROR(ret); @@ -1593,7 +1593,7 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) /* samba4 might not yet respond to a wellknownobject-query */ return ret ? ret : SMB_STRDUP("cn=Computers"); } - + if (strequal(org_unit, "Computers")) { return SMB_STRDUP("cn=Computers"); } @@ -1668,7 +1668,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) for (i=1; i < new_ln; i++) { char *s = NULL; - + if (asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]) == -1) { SAFE_FREE(ret); goto out; @@ -1895,7 +1895,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n } /* add short name spn */ - + if ( (psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name)) == NULL ) { talloc_destroy(ctx); ads_msgfree(ads, res); @@ -1904,13 +1904,13 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n strupper_m(psp1); strlower_m(&psp1[strlen(spn)]); servicePrincipalName[0] = psp1; - + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp1, machine_name)); /* add fully qualified spn */ - + if ( (psp2 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn)) == NULL ) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto out; @@ -1926,18 +1926,18 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n ret = ADS_ERROR(LDAP_NO_MEMORY); goto out; } - + ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); goto out; } - + if ( (dn_string = ads_get_dn(ads, ctx, res)) == NULL ) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto out; } - + ret = ads_gen_mod(ads, dn_string, mods); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); @@ -1974,7 +1974,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, uint32 acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\ UF_DONT_EXPIRE_PASSWD |\ UF_ACCOUNTDISABLE ); - + if (!(ctx = talloc_init("ads_add_machine_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1991,7 +1991,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, if ( !new_dn || !samAccountName ) { goto done; } - + #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif @@ -2003,7 +2003,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, if (!(mods = ads_init_mods(ctx))) { goto done; } - + ads_mod_str(ctx, &mods, "cn", machine_name); ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); ads_mod_strlist(ctx, &mods, "objectClass", objectClass); @@ -2015,7 +2015,7 @@ done: SAFE_FREE(machine_escaped); ads_msgfree(ads, res); talloc_destroy(ctx); - + return ret; } @@ -2254,7 +2254,7 @@ static bool ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da msg = ads_next_entry(ads, msg)) { char *utf8_field; BerElement *b; - + for (utf8_field=ldap_first_attribute(ads->ldap.ld, (LDAPMessage *)msg,&b); utf8_field; @@ -2373,7 +2373,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) return NULL; - + if (values[0] && pull_utf8_talloc(mem_ctx, &ux_string, values[0], &converted_size)) { @@ -2455,7 +2455,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) size_t num_new_strings; unsigned long int range_start; unsigned long int range_end; - + /* we might have been given the whole lot anyway */ if ((strings = ads_pull_strings(ads, mem_ctx, msg, field, num_strings))) { *more_strings = False; @@ -2481,7 +2481,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) *more_strings = False; return NULL; } - + if (sscanf(&range_attr[strlen(expected_range_attrib)], "%lu-%lu", &range_start, &range_end) == 2) { *more_strings = True; @@ -2508,7 +2508,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) } 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", @@ -2521,13 +2521,13 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) strings = TALLOC_REALLOC_ARRAY(mem_ctx, current_strings, char *, *num_strings + num_new_strings); - + if (strings == NULL) { ldap_memfree(range_attr); *more_strings = False; return NULL; } - + if (new_strings && num_new_strings) { memcpy(&strings[*num_strings], new_strings, sizeof(*new_strings) * num_new_strings); @@ -2540,7 +2540,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) "%s;range=%d-*", field, (int)*num_strings); - + if (!*next_attribute) { DEBUG(1, ("talloc_asprintf for next attribute failed!\n")); ldap_memfree(range_attr); @@ -2595,7 +2595,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) values = ldap_get_values(ads->ldap.ld, msg, "objectGUID"); if (!values) return False; - + if (values[0]) { memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT)); smb_uuid_unpack(flat_guid, guid); @@ -2665,7 +2665,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) count++; } } - + ldap_value_free_len(values); return count; } @@ -2700,7 +2700,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) ret = false; } } - + ldap_value_free_len(values); return ret; } @@ -2829,7 +2829,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) } /* but save the time and offset in the original ADS_STRUCT */ - + ads->config.current_time = ads_parse_time(timestr); if (ads->config.current_time != 0) { @@ -2860,7 +2860,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) ADS_STATUS status; LDAPMessage *res; ADS_STRUCT *ads_s = ads; - + *val = DS_DOMAIN_FUNCTION_2000; /* establish a new ldap tcp session if necessary */ @@ -2880,7 +2880,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) /* If the attribute does not exist assume it is a Windows 2000 functional domain */ - + status = ads_do_search(ads_s, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) { if ( status.err.rc == LDAP_NO_SUCH_ATTRIBUTE ) { @@ -2894,7 +2894,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) } DEBUG(3,("ads_domain_func_level: %d\n", *val)); - + ads_msgfree(ads, res); done: @@ -2926,7 +2926,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) return ADS_ERROR_SYSTEM(ENOENT); } ads_msgfree(ads, res); - + return ADS_SUCCESS; } @@ -3301,26 +3301,26 @@ char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine ADS_STATUS status; int count = 0; char *name = NULL; - + status = ads_find_machine_acct(ads, &res, global_myname()); if (!ADS_ERR_OK(status)) { DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", global_myname())); goto out; } - + if ( (count = ads_count_replies(ads, res)) != 1 ) { DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count)); goto out; } - + if ( (name = ads_pull_string(ads, ctx, res, "dNSHostName")) == NULL ) { DEBUG(0,("ads_get_dnshostname: No dNSHostName attribute!\n")); } out: ads_msgfree(ads, res); - + return name; } @@ -3365,26 +3365,26 @@ char* ads_get_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *mach ADS_STATUS status; int count = 0; char *name = NULL; - + status = ads_find_machine_acct(ads, &res, global_myname()); if (!ADS_ERR_OK(status)) { DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", global_myname())); goto out; } - + if ( (count = ads_count_replies(ads, res)) != 1 ) { DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count)); goto out; } - + if ( (name = ads_pull_string(ads, ctx, res, "sAMAccountName")) == NULL ) { DEBUG(0,("ads_get_dnshostname: No sAMAccountName attribute!\n")); } out: ads_msgfree(ads, res); - + return name; } @@ -3700,7 +3700,7 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, status = ads_do_search_all(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, filter, attrs, &res); - + if (!ADS_ERR_OK(status)) { goto out; } @@ -3828,7 +3828,6 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, done: ads_msgfree(ads, res); return result; - } /** diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index c853258a34..0bebcc7c2c 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -7,20 +7,20 @@ Copyright (C) Andrew Bartlett 2002-2003 Copyright (C) Stefan (metze) Metzmacher 2002-2003 Copyright (C) Simo Sorce 2006 - + 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 3 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, see . - + */ /* TODO: @@ -98,10 +98,10 @@ static const char* get_userattr_key2string( int schema_ver, int key ) switch ( schema_ver ) { case SCHEMAVER_SAMBAACCOUNT: return get_attr_key2string( attrib_map_v22, key ); - + case SCHEMAVER_SAMBASAMACCOUNT: return get_attr_key2string( attrib_map_v30, key ); - + default: DEBUG(0,("get_userattr_key2string: unknown schema version specified\n")); break; @@ -118,14 +118,14 @@ const char** get_userattr_list( TALLOC_CTX *mem_ctx, int schema_ver ) switch ( schema_ver ) { case SCHEMAVER_SAMBAACCOUNT: return get_attr_list( mem_ctx, attrib_map_v22 ); - + case SCHEMAVER_SAMBASAMACCOUNT: return get_attr_list( mem_ctx, attrib_map_v30 ); default: DEBUG(0,("get_userattr_list: unknown schema version specified!\n")); break; } - + return NULL; } @@ -140,7 +140,7 @@ static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx, case SCHEMAVER_SAMBAACCOUNT: return get_attr_list( mem_ctx, attrib_map_to_delete_v22 ); - + case SCHEMAVER_SAMBASAMACCOUNT: return get_attr_list( mem_ctx, attrib_map_to_delete_v30 ); @@ -148,7 +148,7 @@ static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx, DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n")); break; } - + return NULL; } @@ -162,7 +162,7 @@ static const char* get_objclass_filter( int schema_ver ) { fstring objclass_filter; char *result; - + switch( schema_ver ) { case SCHEMAVER_SAMBAACCOUNT: fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT ); @@ -175,7 +175,7 @@ static const char* get_objclass_filter( int schema_ver ) objclass_filter[0] = '\0'; break; } - + result = talloc_strdup(talloc_tos(), objclass_filter); SMB_ASSERT(result != NULL); return result; @@ -448,7 +448,7 @@ static int ldapsam_delete_entry(struct ldapsam_privates *priv, } /* Ok, delete only the SAM attributes */ - + for (name = ldap_first_attribute(priv2ld(priv), entry, &ptr); name != NULL; name = ldap_next_attribute(priv2ld(priv), entry, ptr)) { @@ -1501,7 +1501,7 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu int count; const char ** attr_list; int rc; - + attr_list = get_userattr_list( user, ldap_state->schema_ver ); append_attr(user, &attr_list, get_userattr_key2string(ldap_state->schema_ver, @@ -1513,9 +1513,9 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu if ( rc != LDAP_SUCCESS ) return NT_STATUS_NO_SUCH_USER; - + count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result); - + if (count < 1) { DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count)); ldap_msgfree(result); @@ -1572,12 +1572,12 @@ static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state, return rc; break; } - + case SCHEMAVER_SAMBAACCOUNT: if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) { return rc; } - + attr_list = get_userattr_list(NULL, ldap_state->schema_ver); rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list ); @@ -1608,7 +1608,7 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu return NT_STATUS_NO_SUCH_USER; count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result); - + if (count < 1) { DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] " "count=%d\n", sid_string_dbg(sid), count)); @@ -1652,11 +1652,11 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; - + if (!newpwd || !dn) { return NT_STATUS_INVALID_PARAMETER; } - + if (!mods) { DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n")); /* may be password change below however */ @@ -1684,12 +1684,12 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, ldap_op)); return NT_STATUS_INVALID_PARAMETER; } - + if (rc!=LDAP_SUCCESS) { return NT_STATUS_UNSUCCESSFUL; } } - + if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) && (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) && need_update(newpwd, PDB_PLAINTEXT_PW) && @@ -1749,7 +1749,7 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, TALLOC_FREE(utf8_password); return NT_STATUS_UNSUCCESSFUL; } - + TALLOC_FREE(utf8_dn); TALLOC_FREE(utf8_password); ber_free(ber, 1); @@ -1846,7 +1846,7 @@ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, result = NT_STATUS_NO_SUCH_USER; goto done; } - + rc = ldapsam_delete_entry( priv, mem_ctx, entry, priv->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ? @@ -1932,7 +1932,7 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc TALLOC_FREE(dn); return NT_STATUS_OK; } - + ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed); if (mods != NULL) { @@ -2670,7 +2670,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, ret = NT_STATUS_NO_MEMORY; goto done; } - + filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid); if (filter == NULL) { SAFE_FREE(escape_memberuid); @@ -2775,7 +2775,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, } ret = NT_STATUS_OK; - + done: if (values) @@ -3268,7 +3268,7 @@ static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods, rc = ldapsam_delete_entry(priv, mem_ctx, entry, LDAP_OBJ_GROUPMAP, get_attr_list(mem_ctx, groupmap_attr_list_to_delete)); - + if ((rc == LDAP_NAMING_VIOLATION) || (rc == LDAP_NOT_ALLOWED_ON_RDN) || (rc == LDAP_OBJECT_CLASS_VIOLATION)) { @@ -3376,11 +3376,11 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods, while (!bret) { if (!ldap_state->entry) return ret; - + ldap_state->index++; bret = init_group_from_ldap(ldap_state, map, ldap_state->entry); - + ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->entry); @@ -3874,7 +3874,7 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods } *value = (uint32)atol(vals[0]); - + ntstatus = NT_STATUS_OK; out: @@ -3889,7 +3889,7 @@ out: - if user hasn't decided to use account policies inside LDAP just reuse the old tdb values - + - if there is a valid cache entry, return that - if there is an LDAP entry, update cache and return - otherwise set to default, update cache and return @@ -3928,16 +3928,16 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, if (!account_policy_get_default(policy_index, value)) { return ntstatus; } - + /* update_ldap: */ - + ntstatus = ldapsam_set_account_policy(methods, policy_index, *value); if (!NT_STATUS_IS_OK(ntstatus)) { return ntstatus; } - + update_cache: - + if (!cache_account_policy_set(policy_index, *value)) { DEBUG(0,("ldapsam_get_account_policy: failed to update local " "tdb as a cache\n")); @@ -4467,7 +4467,7 @@ static bool ldapuser2displayentry(struct ldap_search_state *state, DEBUG(0, ("talloc failed\n")); return False; } - + vals = ldap_get_values(ld, entry, "sambaSid"); if ((vals == NULL) || (vals[0] == NULL)) { DEBUG(0, ("\"objectSid\" not found\n")); @@ -4623,7 +4623,7 @@ static bool ldapgroup2displayentry(struct ldap_search_state *state, DEBUG(0, ("talloc failed\n")); return False; } - + vals = ldap_get_values(ld, entry, "sambaSid"); if ((vals == NULL) || (vals[0] == NULL)) { DEBUG(0, ("\"objectSid\" not found\n")); @@ -4652,7 +4652,7 @@ static bool ldapgroup2displayentry(struct ldap_search_state *state, return False; } break; - + default: DEBUG(0,("unkown group type: %d\n", group_type)); return False; @@ -4980,7 +4980,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, uid_t uid = -1; NTSTATUS ret; int rc; - + if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') || acb_info & ACB_WSTRUST || acb_info & ACB_SVRTRUST || @@ -5006,7 +5006,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - + if (num_result == 1) { char *tmp; /* check if it is just a posix account. @@ -5035,7 +5035,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, if (num_result == 0) { add_posix = True; } - + /* Create the basic samu structure and generate the mods for the ldap commit */ if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) { DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n")); @@ -5181,7 +5181,7 @@ static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX * int rc; DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct))); - + filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)" "(objectClass=%s)" @@ -5263,7 +5263,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, DOM_SID group_sid; gid_t gid = -1; int rc; - + groupname = escape_ldap_string_alloc(name); filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))", groupname, LDAP_OBJ_POSIXGROUP); @@ -5282,7 +5282,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - + if (num_result == 1) { char *tmp; /* check if it is just a posix group. @@ -5306,7 +5306,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - + gid = strtoul(tmp, NULL, 10); dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry); @@ -5322,7 +5322,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, DEBUG(3,("ldapsam_create_user: Creating new posix group\n")); is_new_entry = True; - + /* lets allocate a new groupid for this group */ if (!winbind_allocate_gid(&gid)) { DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n")); @@ -5519,7 +5519,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, default: return NT_STATUS_UNSUCCESSFUL; } - + /* get member sid */ sid_compose(&member_sid, get_global_sam_sid(), member_rid); @@ -5566,7 +5566,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, /* check if we are trying to remove the member from his primary group */ char *gidstr; gid_t user_gid, group_gid; - + gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx); if (!gidstr) { DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n")); @@ -5574,7 +5574,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, } user_gid = strtoul(gidstr, NULL, 10); - + if (!sid_to_gid(&group_sid, &group_gid)) { DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n")); return NT_STATUS_UNSUCCESSFUL; @@ -5649,7 +5649,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, } return NT_STATUS_UNSUCCESSFUL; } - + return NT_STATUS_OK; } -- cgit