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(-) (limited to 'source3') 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(+) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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 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 --- source3/Makefile.in | 2 +- source3/include/proto.h | 2 -- source3/lib/util.c | 33 --------------------------------- source3/passdb/pdb_interface.c | 20 -------------------- 4 files changed, 1 insertion(+), 56 deletions(-) (limited to 'source3') 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 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(-) (limited to 'source3') 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 + 1 file changed, 1 insertion(+) (limited to 'source3') 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) -- 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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 8da15dc29a920cd6f4d2ed96e8de4fbcd9d1ba11 Mon Sep 17 00:00:00 2001 From: Günther Deschner 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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 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(-) (limited to 'source3') 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 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(+) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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 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(-) (limited to 'source3') 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. --- 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 +- 6 files changed, 9 insertions(+), 1190 deletions(-) delete mode 100644 source3/include/wbc_async.h delete mode 100644 source3/lib/wb_reqtrans.c delete mode 100644 source3/lib/wbclient.c (limited to 'source3') 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; -- 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 --- source3/torture/torture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') 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 --- source3/script/tests/selftest.sh | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') 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 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 (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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(-) (limited to 'source3') 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 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(-) (limited to 'source3') 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 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(-) (limited to 'source3') 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