diff options
31 files changed, 775 insertions, 339 deletions
diff --git a/docs-xml/Samba3-HOWTO/TOSHARG-Install.xml b/docs-xml/Samba3-HOWTO/TOSHARG-Install.xml index c0ffc05613..d13f6ee4ff 100644 --- a/docs-xml/Samba3-HOWTO/TOSHARG-Install.xml +++ b/docs-xml/Samba3-HOWTO/TOSHARG-Install.xml @@ -334,8 +334,8 @@ <variablelist> <varlistentry><term>nmbd</term> <listitem><para> - <indexterm><primary>smbd</primary></indexterm> - <indexterm><primary>starting samba</primary><secondary>smbd</secondary></indexterm> + <indexterm><primary>nmbd</primary></indexterm> + <indexterm><primary>starting samba</primary><secondary>nmbd</secondary></indexterm> This daemon handles all name registration and resolution requests. It is the primary vehicle involved in network browsing. It handles all UDP-based protocols. The <command>nmbd</command> daemon should be the first command started as part of the Samba startup process. @@ -344,8 +344,8 @@ <varlistentry><term>smbd</term> <listitem><para> - <indexterm><primary>nmbd</primary></indexterm> - <indexterm><primary>starting samba</primary><secondary>nmbd</secondary></indexterm> + <indexterm><primary>smbd</primary></indexterm> + <indexterm><primary>starting samba</primary><secondary>smbd</secondary></indexterm> This daemon handles all TCP/IP-based connection services for file- and print-based operations. It also manages local authentication. It should be started immediately following the startup of <command>nmbd</command>. </para></listitem> diff --git a/nsswitch/winbind_nss_aix.c b/nsswitch/winbind_nss_aix.c index 17578cf350..66200f3562 100644 --- a/nsswitch/winbind_nss_aix.c +++ b/nsswitch/winbind_nss_aix.c @@ -237,6 +237,9 @@ static struct group *fill_grent(struct winbindd_gr *gr, char *gr_mem) result->gr_mem = (char **)malloc(sizeof(char *) * (gr->num_gr_mem+1)); if (!result->gr_mem) { + free(result->gr_name); + free(result->gr_passwd); + free(result); errno = ENOMEM; return NULL; } diff --git a/source3/Makefile.in b/source3/Makefile.in index 1ad1f5acc2..1120092f90 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -2151,7 +2151,7 @@ $(LIBSMBCLIENT_SHARED_TARGET_SONAME): $(BINARY_PREREQS) $(LIBSMBCLIENT_OBJ) $(LI @echo Linking shared library $@ @$(SHLD_DSO) $(LIBSMBCLIENT_OBJ) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(LIBWBCLIENT_LIBS) $(LIBS) \ - $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ + $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) $(ZLIB_LIBS) \ @SONAMEFLAG@`basename $@` $(LIBSMBCLIENT_SHARED_TARGET): $(LIBSMBCLIENT_SHARED_TARGET_SONAME) @@ -3076,7 +3076,7 @@ etags:: find $(srcdir)/.. -name "*.[ch]" | xargs -n 100 etags --append $(ETAGS_OPTIONS) ctags:: - ctags $(CTAGS_OPTIONS) `find $(srcdir)/.. -name "*.[ch]" | grep -v include/proto\.h` + ctags $(CTAGS_OPTIONS) `find $(srcdir)/.. -name "*.[ch]" | grep -v proto\.h` realclean:: clean -rm -f config.log bin/.dummy script/findsmb script/gen-8bit-gap.sh diff --git a/source3/lib/dbwrap_ctdb.c b/source3/lib/dbwrap_ctdb.c index 4a5bf6d81a..e38f76fcf6 100644 --- a/source3/lib/dbwrap_ctdb.c +++ b/source3/lib/dbwrap_ctdb.c @@ -212,14 +212,20 @@ static struct ctdb_rec_data *db_ctdb_marshall_loop_next(struct ctdb_marshall_buf -/* start a transaction on a database */ +/** + * CTDB transaction destructor + */ static int db_ctdb_transaction_destructor(struct db_ctdb_transaction_handle *h) { tdb_transaction_cancel(h->ctx->wtdb->tdb); return 0; } -/* start a transaction on a database */ +/** + * start a transaction on a ctdb database: + * - lock the transaction lock key + * - start the tdb transaction + */ static int db_ctdb_transaction_fetch_start(struct db_ctdb_transaction_handle *h) { struct db_record *rh; @@ -268,7 +274,10 @@ again: } -/* start a transaction on a database */ +/** + * CTDB dbwrap API: transaction_start function + * starts a transaction on a persistent database + */ static int db_ctdb_transaction_start(struct db_context *db) { struct db_ctdb_transaction_handle *h; diff --git a/source3/pam_smbpass/pam_smb_auth.c b/source3/pam_smbpass/pam_smb_auth.c index 3dceb52c7d..b5a6a473b6 100644 --- a/source3/pam_smbpass/pam_smb_auth.c +++ b/source3/pam_smbpass/pam_smb_auth.c @@ -179,7 +179,7 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, retval = PAM_SUCCESS; - pam_get_data(pamh, "smb_setcred_return", (const void **) &pretval); + _pam_get_data(pamh, "smb_setcred_return", &pretval); if(pretval) { retval = *pretval; SAFE_FREE(pretval); @@ -199,7 +199,7 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl, int retval; /* Get the authtok; if we don't have one, silently fail. */ - retval = pam_get_item( pamh, PAM_AUTHTOK, (const void **) &pass ); + retval = _pam_get_item( pamh, PAM_AUTHTOK, &pass ); if (retval != PAM_SUCCESS) { _log_err( LOG_ALERT diff --git a/source3/pam_smbpass/pam_smb_passwd.c b/source3/pam_smbpass/pam_smb_passwd.c index b6de43ff97..dce6e01ae9 100644 --- a/source3/pam_smbpass/pam_smb_passwd.c +++ b/source3/pam_smbpass/pam_smb_passwd.c @@ -229,11 +229,11 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, */ if (off( SMB_NOT_SET_PASS, ctrl )) { - retval = pam_get_item( pamh, PAM_OLDAUTHTOK, - (const void **)&pass_old ); + retval = _pam_get_item( pamh, PAM_OLDAUTHTOK, + &pass_old ); } else { - retval = pam_get_data( pamh, _SMB_OLD_AUTHTOK, - (const void **)&pass_old ); + retval = _pam_get_data( pamh, _SMB_OLD_AUTHTOK, + &pass_old ); if (retval == PAM_NO_MODULE_DATA) { pass_old = NULL; retval = PAM_SUCCESS; diff --git a/source3/pam_smbpass/support.c b/source3/pam_smbpass/support.c index 1e66f40363..b6cf3a886d 100644 --- a/source3/pam_smbpass/support.c +++ b/source3/pam_smbpass/support.c @@ -85,7 +85,7 @@ int converse( pam_handle_t * pamh, int ctrl, int nargs int retval; struct pam_conv *conv; - retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv); + retval = _pam_get_item(pamh, PAM_CONV, &conv); if (retval == PAM_SUCCESS) { retval = conv->conv(nargs, (const struct pam_message **) message @@ -278,7 +278,7 @@ void _cleanup_failures( pam_handle_t * pamh, void *fl, int err ) /* log the number of authentication failures */ if (failure->count != 0) { - pam_get_item( pamh, PAM_SERVICE, (const void **) &service ); + _pam_get_item( pamh, PAM_SERVICE, &service ); _log_err( LOG_NOTICE , "%d authentication %s " "from %s for service %s as %s(%d)" @@ -334,7 +334,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass, } else { const char *service; - pam_get_item( pamh, PAM_SERVICE, (const void **)&service ); + _pam_get_item( pamh, PAM_SERVICE, &service ); _log_err( LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); return PAM_AUTH_ERR; @@ -369,7 +369,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass, const char *service; - pam_get_item( pamh, PAM_SERVICE, (const void **)&service ); + _pam_get_item( pamh, PAM_SERVICE, &service ); if (data_name != NULL) { struct _pam_failed_auth *newauth = NULL; @@ -382,7 +382,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass, if (newauth != NULL) { /* any previous failures for this user ? */ - pam_get_data(pamh, data_name, (const void **) &old); + _pam_get_data(pamh, data_name, &old); if (old != NULL) { newauth->count = old->count + 1; @@ -487,7 +487,7 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl, /* should we obtain the password from a PAM item ? */ if (on(SMB_TRY_FIRST_PASS, ctrl) || on(SMB_USE_FIRST_PASS, ctrl)) { - retval = pam_get_item( pamh, authtok_flag, (const void **) &item ); + retval = _pam_get_item( pamh, authtok_flag, &item ); if (retval != PAM_SUCCESS) { /* very strange. */ _log_err( LOG_ALERT @@ -580,8 +580,8 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl, retval = pam_set_item( pamh, authtok_flag, (const void *)token ); _pam_delete( token ); /* clean it up */ if (retval != PAM_SUCCESS - || (retval = pam_get_item( pamh, authtok_flag - ,(const void **)&item )) != PAM_SUCCESS) + || (retval = _pam_get_item( pamh, authtok_flag + ,&item )) != PAM_SUCCESS) { _log_err( LOG_CRIT, "error manipulating password" ); return retval; @@ -594,7 +594,7 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl, retval = pam_set_data( pamh, data_name, (void *) token, _cleanup ); if (retval != PAM_SUCCESS - || (retval = pam_get_data( pamh, data_name, (const void **)&item )) + || (retval = _pam_get_data( pamh, data_name, &item )) != PAM_SUCCESS) { _log_err( LOG_CRIT, "error manipulating password data [%s]" @@ -632,3 +632,23 @@ int _pam_smb_approve_pass(pam_handle_t * pamh, return PAM_SUCCESS; } + +/* + * Work around the pam API that has functions with void ** as parameters + * These lead to strict aliasing warnings with gcc. + */ +int _pam_get_item(const pam_handle_t *pamh, + int item_type, + const void *_item) +{ + const void **item = (const void **)_item; + return pam_get_item(pamh, item_type, item); +} + +int _pam_get_data(const pam_handle_t *pamh, + const char *module_data_name, + const void *_data) +{ + const void **data = (const void **)_data; + return pam_get_data(pamh, module_data_name, data); +} diff --git a/source3/pam_smbpass/support.h b/source3/pam_smbpass/support.h index 5ac48c3afa..87f1690a60 100644 --- a/source3/pam_smbpass/support.h +++ b/source3/pam_smbpass/support.h @@ -48,3 +48,10 @@ extern int _smb_read_password( pam_handle_t *, unsigned int, const char*, extern int _pam_smb_approve_pass(pam_handle_t *, unsigned int, const char *, const char *); + +int _pam_get_item(const pam_handle_t *pamh, + int item_type, + const void *_item); +int _pam_get_data(const pam_handle_t *pamh, + const char *module_data_name, + const void *_data); diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index d528c802e5..26bc44c6ff 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -1109,6 +1109,12 @@ NTSTATUS _samr_EnumDomainGroups(pipes_struct *p, make_group_sam_entry_list(p->mem_ctx, &samr_entries, num_groups, groups); + if (MAX_SAM_ENTRIES <= num_groups) { + status = STATUS_MORE_ENTRIES; + } else { + status = NT_STATUS_OK; + } + samr_array->count = num_groups; samr_array->entries = samr_entries; @@ -1174,6 +1180,12 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p, DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__)); + if (MAX_SAM_ENTRIES <= num_aliases) { + status = STATUS_MORE_ENTRIES; + } else { + status = NT_STATUS_OK; + } + samr_array->count = num_aliases; samr_array->entries = samr_entries; diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 96484f0982..e074544518 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -813,12 +813,11 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, /* Get domain policy handle */ - result = rpccli_samr_OpenDomain(cli, mem_ctx, - &connect_pol, - access_mask, - &domain_sid, - &domain_pol); - + result = get_domain_handle(cli, mem_ctx, "domain", + &connect_pol, + access_mask, + &domain_sid, + &domain_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -888,12 +887,11 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, /* Get domain policy handle */ - result = rpccli_samr_OpenDomain(cli, mem_ctx, - &connect_pol, - access_mask, - &domain_sid, - &domain_pol); - + result = get_domain_handle(cli, mem_ctx, "domain", + &connect_pol, + access_mask, + &domain_sid, + &domain_pol); if (!NT_STATUS_IS_OK(result)) goto done; diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh index 1e84d1c0b8..1f3ad761b2 100755 --- a/source3/script/tests/selftest.sh +++ b/source3/script/tests/selftest.sh @@ -217,10 +217,10 @@ cat >$SERVERCONFFILE<<EOF time server = yes add user script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --path $NSS_WRAPPER_PASSWD --type passwd --action add --name %u - add group script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper_pl --path $NSS_WRAPPER_GROUP --type group --action add --name %g + add group script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --path $NSS_WRAPPER_GROUP --type group --action add --name %g add machine script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --path $NSS_WRAPPER_PASSWD --type passwd --action add --name %u delete user script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --path $NSS_WRAPPER_PASSWD --type passwd --action delete --name %u - delete group script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper_pl --path $NSS_WRAPPER_GROUP --type group --action delete --name %g + delete group script = $PERL $SRCDIR/../lib/nss_wrapper/nss_wrapper.pl --path $NSS_WRAPPER_GROUP --type group --action delete --name %g kernel oplocks = no kernel change notify = no diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh index a3c8e09fa8..0bcf3695ed 100755 --- a/source3/script/tests/test_posix_s3.sh +++ b/source3/script/tests/test_posix_s3.sh @@ -42,7 +42,7 @@ rpc="$rpc RPC-SAMBA3-SPOOLSS RPC-SAMBA3-WKSSVC" rpc="$rpc RPC-NETLOGSAMBA3 RPC-SAMBA3SESSIONKEY RPC-SAMBA3-GETUSERNAME" rpc="$rpc RPC-SVCCTL RPC-SPOOLSS RPC-SPOOLSS-WIN RPC-NTSVCS" 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-JOIN" +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" # NOTE: to enable the UNIX-WHOAMI test, we need to change the default share diff --git a/source3/torture/smbiconv.c b/source3/torture/smbiconv.c index 72fbdc470f..47353d2a94 100644 --- a/source3/torture/smbiconv.c +++ b/source3/torture/smbiconv.c @@ -216,6 +216,7 @@ int main(int argc, char *argv[]) cd = smb_iconv_open(to, from); if (cd == (smb_iconv_t)-1) { DEBUG(0,("unable to find from or to encoding, exiting...\n")); + if (out != stdout) fclose(out); return 1; } diff --git a/source3/utils/dbwrap_tool.c b/source3/utils/dbwrap_tool.c index 5172112a4c..38b3903265 100644 --- a/source3/utils/dbwrap_tool.c +++ b/source3/utils/dbwrap_tool.c @@ -23,7 +23,7 @@ extern bool AllowDebugChange; -typedef enum { OP_FETCH, OP_STORE, OP_DELETE } dbwrap_op; +typedef enum { OP_FETCH, OP_STORE, OP_DELETE, OP_ERASE, OP_LISTKEYS } dbwrap_op; typedef enum { TYPE_INT32, TYPE_UINT32 } dbwrap_type; @@ -111,6 +111,67 @@ static int dbwrap_tool_delete(struct db_context *db, return 0; } +static int delete_fn(struct db_record *rec, void *priv) +{ + rec->delete_rec(rec); + return 0; +} + +/** + * dbwrap_tool_erase: erase the whole data base + * the keyname argument is not used. + */ +static int dbwrap_tool_erase(struct db_context *db, + const char *keyname, + void *data) +{ + int ret; + + ret = db->traverse(db, delete_fn, NULL); + + if (ret < 0) { + d_fprintf(stderr, "ERROR erasing the database\n"); + return -1; + } + + return 0; +} + +static int listkey_fn(struct db_record *rec, void *private_data) +{ + int length = rec->key.dsize; + unsigned char *p = (unsigned char *)rec->key.dptr; + + while (length--) { + if (isprint(*p) && !strchr("\"\\", *p)) { + d_printf("%c", *p); + } else { + d_printf("\\%02X", *p); + } + p++; + } + + d_printf("\n"); + + return 0; +} + +static int dbwrap_tool_listkeys(struct db_context *db, + const char *keyname, + void *data) +{ + int ret; + + ret = db->traverse_read(db, listkey_fn, NULL); + + if (ret < 0) { + d_fprintf(stderr, "ERROR listing db keys\n"); + return -1; + } + + return 0; +} + struct dbwrap_op_dispatch_table { dbwrap_op op; dbwrap_type type; @@ -125,7 +186,8 @@ struct dbwrap_op_dispatch_table dispatch_table[] = { { OP_STORE, TYPE_INT32, dbwrap_tool_store_int32 }, { OP_STORE, TYPE_UINT32, dbwrap_tool_store_uint32 }, { OP_DELETE, TYPE_INT32, dbwrap_tool_delete }, - { OP_DELETE, TYPE_UINT32, dbwrap_tool_delete }, + { OP_ERASE, TYPE_INT32, dbwrap_tool_erase }, + { OP_LISTKEYS, TYPE_INT32, dbwrap_tool_listkeys }, { 0, 0, NULL }, }; @@ -140,7 +202,7 @@ int main(int argc, const char **argv) const char *dbname; const char *opname; dbwrap_op op; - const char *keyname; + const char *keyname = ""; const char *keytype = "int32"; dbwrap_type type; const char *valuestr = "0"; @@ -156,10 +218,10 @@ int main(int argc, const char **argv) AllowDebugChange = false; lp_load(get_dyn_CONFIGFILE(), true, false, false, true); - if ((argc != 4) && (argc != 5) && (argc != 6)) { + if ((argc < 3) || (argc > 6)) { d_fprintf(stderr, - "USAGE: %s <database> <op> <key> [<type> [<value>]]\n" - " ops: fetch, store, delete\n" + "USAGE: %s <database> <op> [<key> [<type> [<value>]]]\n" + " ops: fetch, store, delete, erase, listkeys\n" " types: int32, uint32\n", argv[0]); goto done; @@ -167,7 +229,6 @@ int main(int argc, const char **argv) dbname = argv[1]; opname = argv[2]; - keyname = argv[3]; if (strcmp(opname, "store") == 0) { if (argc != 6) { @@ -177,6 +238,7 @@ int main(int argc, const char **argv) } valuestr = argv[5]; keytype = argv[4]; + keyname = argv[3]; op = OP_STORE; } else if (strcmp(opname, "fetch") == 0) { if (argc != 5) { @@ -186,13 +248,29 @@ int main(int argc, const char **argv) } op = OP_FETCH; keytype = argv[4]; + keyname = argv[3]; } else if (strcmp(opname, "delete") == 0) { if (argc != 4) { d_fprintf(stderr, "ERROR: operation 'delete' does " "not allow type nor value argument\n"); goto done; } + keyname = argv[3]; op = OP_DELETE; + } else if (strcmp(opname, "erase") == 0) { + if (argc != 3) { + d_fprintf(stderr, "ERROR: operation 'erase' does " + "not take a key argument\n"); + goto done; + } + op = OP_ERASE; + } else if (strcmp(opname, "listkeys") == 0) { + if (argc != 3) { + d_fprintf(stderr, "ERROR: operation 'listkeys' does " + "not take a key argument\n"); + goto done; + } + op = OP_LISTKEYS; } else { d_fprintf(stderr, "ERROR: invalid op '%s' specified\n" diff --git a/source3/utils/log2pcaphex.c b/source3/utils/log2pcaphex.c index 072d659bf0..b1a8a27c22 100644 --- a/source3/utils/log2pcaphex.c +++ b/source3/utils/log2pcaphex.c @@ -364,5 +364,13 @@ int main (int argc, char **argv) } } + if (in != stdin) { + fclose(in); + } + + if (out != stdout) { + fclose(out); + } + return 0; } diff --git a/source3/utils/net.c b/source3/utils/net.c index 9cd41c5b37..0e3946f5a5 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -625,7 +625,6 @@ static struct functable net_func[] = { int main(int argc, const char **argv) { int opt,i; - char *p; int rc = 0; int argc_new = 0; const char ** argv_new; @@ -636,12 +635,10 @@ static struct functable net_func[] = { struct poptOption long_options[] = { {"help", 'h', POPT_ARG_NONE, 0, 'h'}, {"workgroup", 'w', POPT_ARG_STRING, &c->opt_target_workgroup}, - {"user", 'U', POPT_ARG_STRING, &c->opt_user_name, 'U'}, {"ipaddress", 'I', POPT_ARG_STRING, 0,'I'}, {"port", 'p', POPT_ARG_INT, &c->opt_port}, {"myname", 'n', POPT_ARG_STRING, &c->opt_requester_name}, {"server", 'S', POPT_ARG_STRING, &c->opt_host}, - {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" }, {"container", 'c', POPT_ARG_STRING, &c->opt_container}, {"comment", 'C', POPT_ARG_STRING, &c->opt_comment}, {"maxusers", 'M', POPT_ARG_INT, &c->opt_maxusers}, @@ -652,15 +649,13 @@ static struct functable net_func[] = { {"stdin", 'i', POPT_ARG_NONE, &c->opt_stdin}, {"timeout", 't', POPT_ARG_INT, &c->opt_timeout}, {"request-timeout",0,POPT_ARG_INT, &c->opt_request_timeout}, - {"machine-pass",'P', POPT_ARG_NONE, &c->opt_machine_pass}, - {"kerberos", 'k', POPT_ARG_NONE, &c->opt_kerberos}, {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup}, {"verbose", 'v', POPT_ARG_NONE, &c->opt_verbose}, {"test", 'T', POPT_ARG_NONE, &c->opt_testmode}, /* Options for 'net groupmap set' */ {"local", 'L', POPT_ARG_NONE, &c->opt_localgroup}, {"domain", 'D', POPT_ARG_NONE, &c->opt_domaingroup}, - {"ntname", 'N', POPT_ARG_STRING, &c->opt_newntname}, + {"ntname", 0, POPT_ARG_STRING, &c->opt_newntname}, {"rid", 'R', POPT_ARG_INT, &c->opt_rid}, /* Options for 'net rpc share migrate' */ {"acls", 0, POPT_ARG_NONE, &c->opt_acls}, @@ -675,6 +670,7 @@ static struct functable net_func[] = { {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries}, POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS { 0, 0, 0, 0} }; @@ -688,6 +684,13 @@ static struct functable net_func[] = { dbf = x_stderr; c->private_data = net_func; + c->auth_info = user_auth_info_init(frame); + if (c->auth_info == NULL) { + d_fprintf(stderr, "\nOut of memory!\n"); + exit(1); + } + popt_common_set_auth_info(c->auth_info); + pc = poptGetContext(NULL, argc, (const char **) argv, long_options, POPT_CONTEXT_KEEP_FIRST); @@ -695,9 +698,7 @@ static struct functable net_func[] = { switch (opt) { case 'h': c->display_usage = true; - break; - case 'e': - c->smb_encrypt = true; + set_cmdline_auth_info_password(c->auth_info, ""); break; case 'I': if (!interpret_string_addr(&c->opt_dest_ip, @@ -707,15 +708,6 @@ static struct functable net_func[] = { c->opt_have_ip = true; } break; - case 'U': - c->opt_user_specified = true; - c->opt_user_name = SMB_STRDUP(c->opt_user_name); - p = strchr(c->opt_user_name,'%'); - if (p) { - *p = 0; - c->opt_password = p+1; - } - break; default: d_fprintf(stderr, "\nInvalid option %s: %s\n", poptBadOption(pc, 0), poptStrerror(opt)); @@ -749,10 +741,6 @@ static struct functable net_func[] = { set_global_myname(c->opt_requester_name); } - if (!c->opt_user_name && getenv("LOGNAME")) { - c->opt_user_name = getenv("LOGNAME"); - } - if (!c->opt_workgroup) { c->opt_workgroup = smb_xstrdup(lp_workgroup()); } @@ -770,17 +758,6 @@ static struct functable net_func[] = { that it won't assert becouse we are not root */ sec_init(); - if (c->opt_machine_pass) { - /* it is very useful to be able to make ads queries as the - machine account for testing purposes and for domain leave */ - - net_use_krb_machine_account(c); - } - - if (!c->opt_password) { - c->opt_password = getenv("PASSWD"); - } - rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func); DEBUG(2,("return code = %d\n", rc)); diff --git a/source3/utils/net.h b/source3/utils/net.h index d88f962d41..f604d96361 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -28,11 +28,8 @@ struct net_context { const char *opt_requester_name; const char *opt_host; - const char *opt_password; - const char *opt_user_name; - bool opt_user_specified; - const char *opt_workgroup; int opt_long_list_entries; + const char *opt_workgroup; int opt_reboot; int opt_force; int opt_stdin; @@ -45,7 +42,6 @@ struct net_context { int opt_timeout; int opt_request_timeout; const char *opt_target_workgroup; - int opt_machine_pass; int opt_localgroup; int opt_domaingroup; int do_talloc_report; @@ -57,15 +53,14 @@ struct net_context { const char *opt_exclude; const char *opt_destination; int opt_testmode; - bool opt_kerberos; int opt_force_full_repl; int opt_single_obj_repl; int opt_clean_old_entries; int opt_have_ip; struct sockaddr_storage opt_dest_ip; - bool smb_encrypt; struct libnetapi_ctx *netapi_ctx; + struct user_auth_info *auth_info; bool display_usage; void *private_data; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 8e927becbe..4503231566 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -231,32 +231,22 @@ retry_connect: ads = ads_init(realm, c->opt_target_workgroup, c->opt_host); - if (!c->opt_user_name) { - c->opt_user_name = "administrator"; - } - - if (c->opt_user_specified) { - need_password = true; - } - retry: - if (!c->opt_password && need_password && !c->opt_machine_pass) { - c->opt_password = net_prompt_pass(c, c->opt_user_name); - if (!c->opt_password) { - ads_destroy(&ads); - return ADS_ERROR(LDAP_NO_MEMORY); - } + if (need_password) { + set_cmdline_auth_info_getpass(c->auth_info); } - if (c->opt_password) { + if (get_cmdline_auth_info_got_pass(c->auth_info)) { use_in_memory_ccache(); SAFE_FREE(ads->auth.password); - ads->auth.password = smb_xstrdup(c->opt_password); + ads->auth.password = smb_xstrdup( + get_cmdline_auth_info_password(c->auth_info)); } ads->auth.flags |= auth_flags; SAFE_FREE(ads->auth.user_name); - ads->auth.user_name = smb_xstrdup(c->opt_user_name); + ads->auth.user_name = smb_xstrdup( + get_cmdline_auth_info_username(c->auth_info)); /* * If the username is of the form "name@realm", @@ -875,6 +865,7 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv) TALLOC_CTX *ctx; struct libnet_UnjoinCtx *r = NULL; WERROR werr; + struct user_auth_info *ai = c->auth_info; if (c->display_usage) { d_printf("Usage:\n" @@ -893,7 +884,7 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv) return -1; } - if (!c->opt_kerberos) { + if (!get_cmdline_auth_info_use_kerberos(ai)) { use_in_memory_ccache(); } @@ -903,12 +894,14 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv) return -1; } + set_cmdline_auth_info_getpass(ai); + r->in.debug = true; - r->in.use_kerberos = c->opt_kerberos; + r->in.use_kerberos = get_cmdline_auth_info_use_kerberos(ai); r->in.dc_name = c->opt_host; r->in.domain_name = lp_realm(); - r->in.admin_account = c->opt_user_name; - r->in.admin_password = net_prompt_pass(c, c->opt_user_name); + r->in.admin_account = get_cmdline_auth_info_username(ai); + r->in.admin_password = get_cmdline_auth_info_password(ai); r->in.modify_config = lp_config_backend_is_registry(); r->in.unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE; @@ -959,7 +952,7 @@ static NTSTATUS net_ads_join_ok(struct net_context *c) return NT_STATUS_ACCESS_DENIED; } - net_use_krb_machine_account(c); + set_cmdline_auth_info_use_machine_account(c->auth_info); status = ads_startup(c, true, &ads); if (!ADS_ERR_OK(status)) { @@ -1190,6 +1183,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) const char *os_name = NULL; const char *os_version = NULL; bool modify_config = lp_config_backend_is_registry(); + struct user_auth_info *ai = c->auth_info;; if (c->display_usage) return net_ads_join_usage(c, argc, argv); @@ -1209,7 +1203,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) goto fail; } - if (!c->opt_kerberos) { + if (!get_cmdline_auth_info_use_kerberos(ai)) { use_in_memory_ccache(); } @@ -1259,6 +1253,8 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) /* Do the domain join here */ + set_cmdline_auth_info_getpass(ai); + r->in.domain_name = domain; r->in.create_upn = createupn; r->in.upn = machineupn; @@ -1266,10 +1262,10 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) r->in.os_name = os_name; r->in.os_version = os_version; r->in.dc_name = c->opt_host; - r->in.admin_account = c->opt_user_name; - r->in.admin_password = net_prompt_pass(c, c->opt_user_name); + r->in.admin_account = get_cmdline_auth_info_username(ai); + r->in.admin_password = get_cmdline_auth_info_password(ai); r->in.debug = true; - r->in.use_kerberos = c->opt_kerberos; + r->in.use_kerberos = get_cmdline_auth_info_use_kerberos(ai); r->in.modify_config = modify_config; r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | @@ -1580,6 +1576,7 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * char *prt_dn, *srv_dn, **srv_cn; char *srv_cn_escaped = NULL, *printername_escaped = NULL; LDAPMessage *res = NULL; + struct user_auth_info *ai = c->auth_info; if (argc < 1 || c->display_usage) { d_printf("Usage:\n" @@ -1611,8 +1608,9 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * nt_status = cli_full_connection(&cli, global_myname(), servername, &server_ss, 0, "IPC$", "IPC", - c->opt_user_name, c->opt_workgroup, - c->opt_password ? c->opt_password : "", + get_cmdline_auth_info_username(ai), + c->opt_workgroup, + get_cmdline_auth_info_password(ai), CLI_FULL_CONNECTION_USE_KERBEROS, Undefined, NULL); @@ -1800,8 +1798,8 @@ static int net_ads_printer(struct net_context *c, int argc, const char **argv) static int net_ads_password(struct net_context *c, int argc, const char **argv) { ADS_STRUCT *ads; - const char *auth_principal = c->opt_user_name; - const char *auth_password = c->opt_password; + const char *auth_principal; + const char *auth_password; char *realm = NULL; char *new_password = NULL; char *chr, *prompt; @@ -1816,10 +1814,9 @@ static int net_ads_password(struct net_context *c, int argc, const char **argv) return 0; } - if (c->opt_user_name == NULL || c->opt_password == NULL) { - d_fprintf(stderr, "You must supply an administrator username/password\n"); - return -1; - } + auth_principal = get_cmdline_auth_info_username(c->auth_info); + set_cmdline_auth_info_getpass(c->auth_info); + auth_password = get_cmdline_auth_info_password(c->auth_info); if (argc < 1) { d_fprintf(stderr, "ERROR: You must say which username to change password for\n"); @@ -1901,7 +1898,7 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv) return -1; } - net_use_krb_machine_account(c); + set_cmdline_auth_info_use_machine_account(c->auth_info); use_in_memory_ccache(); @@ -2283,6 +2280,7 @@ static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **ar TALLOC_CTX *mem_ctx = NULL; NTSTATUS status; int ret = -1; + struct user_auth_info *ai = c->auth_info; if (c->display_usage) { d_printf("Usage:\n" @@ -2296,11 +2294,11 @@ static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **ar goto out; } - c->opt_password = net_prompt_pass(c, c->opt_user_name); + set_cmdline_auth_info_getpass(ai); status = kerberos_return_pac(mem_ctx, - c->opt_user_name, - c->opt_password, + get_cmdline_auth_info_username(ai), + get_cmdline_auth_info_password(ai), 0, NULL, NULL, @@ -2333,6 +2331,7 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char ** TALLOC_CTX *mem_ctx = NULL; int ret = -1; NTSTATUS status; + struct user_auth_info *ai = c->auth_info; if (c->display_usage) { d_printf("Usage:\n" @@ -2346,10 +2345,10 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char ** goto out; } - c->opt_password = net_prompt_pass(c, c->opt_user_name); + set_cmdline_auth_info_getpass(ai); - ret = kerberos_kinit_password_ext(c->opt_user_name, - c->opt_password, + ret = kerberos_kinit_password_ext(get_cmdline_auth_info_username(ai), + get_cmdline_auth_info_password(ai), 0, NULL, NULL, diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c index 401079777f..a13f52c519 100644 --- a/source3/utils/net_dom.c +++ b/source3/utils/net_dom.c @@ -368,9 +368,11 @@ int net_dom(struct net_context *c, int argc, const char **argv) return -1; } - libnetapi_set_username(c->netapi_ctx, c->opt_user_name); - libnetapi_set_password(c->netapi_ctx, c->opt_password); - if (c->opt_kerberos) { + libnetapi_set_username(c->netapi_ctx, + get_cmdline_auth_info_username(c->auth_info)); + libnetapi_set_password(c->netapi_ctx, + get_cmdline_auth_info_password(c->auth_info)); + if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { libnetapi_set_use_kerberos(c->netapi_ctx); } diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index 0502373aa2..5a170790c5 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -65,5 +65,6 @@ int net_help(struct net_context *c, int argc, const char **argv) } c->display_usage = true; + set_cmdline_auth_info_password(c->auth_info, ""); return net_run_function(c, argc, argv, "net help", func); } diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h index 75ac032db9..8a09147aad 100644 --- a/source3/utils/net_proto.h +++ b/source3/utils/net_proto.h @@ -459,8 +459,6 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst, struct rpc_pipe_client **pp_pipe_hnd, const struct ndr_syntax_id *interface); -int net_use_krb_machine_account(struct net_context *c); -int net_use_machine_account(struct net_context *c); bool net_find_server(struct net_context *c, const char *domain, unsigned flags, @@ -475,7 +473,6 @@ NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain, const char *server, struct sockaddr_storage *pss, unsigned flags, struct cli_state **pcli); -const char *net_prompt_pass(struct net_context *c, const char *user); int net_run_function(struct net_context *c, int argc, const char **argv, const char *whoami, struct functable *table); void net_display_usage_from_functable(struct functable *table); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index f6f90030fe..0118b4818a 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -25,7 +25,8 @@ #include "../libcli/auth/libcli_auth.h" static int net_mode_share; -static bool sync_files(struct copy_clistate *cp_clistate, const char *mask); +static bool sync_files(struct copy_clistate *cp_clistate, const char *mask, + const struct user_auth_info *auth_info); /** * @file net_rpc.c @@ -122,6 +123,7 @@ int run_rpc_command(struct net_context *c, DOM_SID *domain_sid; const char *domain_name; int ret = -1; + struct user_auth_info *ai = c->auth_info; /* make use of cli_state handed over as an argument, if possible */ if (!cli_arg) { @@ -171,8 +173,10 @@ int run_rpc_command(struct net_context *c, nt_status = cli_rpc_pipe_open_ntlmssp( cli, interface, PIPE_AUTH_LEVEL_PRIVACY, - lp_workgroup(), c->opt_user_name, - c->opt_password, &pipe_hnd); + lp_workgroup(), + get_cmdline_auth_info_username(ai), + get_cmdline_auth_info_password(ai), + &pipe_hnd); } else { nt_status = cli_rpc_pipe_open_noauth( cli, interface, @@ -940,9 +944,12 @@ int net_rpc_user(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - libnetapi_set_username(c->netapi_ctx, c->opt_user_name); - libnetapi_set_password(c->netapi_ctx, c->opt_password); - if (c->opt_kerberos) { + set_cmdline_auth_info_getpass(c->auth_info); + libnetapi_set_username(c->netapi_ctx, + get_cmdline_auth_info_username(c->auth_info)); + libnetapi_set_password(c->netapi_ctx, + get_cmdline_auth_info_password(c->auth_info)); + if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -2756,9 +2763,12 @@ int net_rpc_group(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - libnetapi_set_username(c->netapi_ctx, c->opt_user_name); - libnetapi_set_password(c->netapi_ctx, c->opt_password); - if (c->opt_kerberos) { + set_cmdline_auth_info_getpass(c->auth_info); + libnetapi_set_username(c->netapi_ctx, + get_cmdline_auth_info_username(c->auth_info)); + libnetapi_set_password(c->netapi_ctx, + get_cmdline_auth_info_password(c->auth_info)); + if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -3245,7 +3255,7 @@ static void copy_fn(const char *mnt, file_info *f, old_dir = local_state->cwd; local_state->cwd = dir; - if (!sync_files(local_state, new_mask)) + if (!sync_files(local_state, new_mask, c->auth_info)) printf("could not handle files\n"); local_state->cwd = old_dir; @@ -3292,15 +3302,18 @@ static void copy_fn(const char *mnt, file_info *f, * * @return Boolean result **/ -static bool sync_files(struct copy_clistate *cp_clistate, const char *mask) +static bool sync_files(struct copy_clistate *cp_clistate, const char *mask, + const struct user_auth_info *auth_info) { struct cli_state *targetcli; char *targetpath = NULL; DEBUG(3,("calling cli_list with mask: %s\n", mask)); - if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src, - mask, &targetcli, &targetpath ) ) { + + if ( !cli_resolve_path(talloc_tos(), "", auth_info, + cp_clistate->cli_share_src, mask, &targetcli, + &targetpath ) ) { d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n", mask, cli_errstr(cp_clistate->cli_share_src)); return false; @@ -3463,7 +3476,7 @@ static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c, goto done; } - if (!sync_files(&cp_clistate, mask)) { + if (!sync_files(&cp_clistate, mask, c->auth_info)) { d_fprintf(stderr, "could not handle files for share: %s\n", info502.name); nt_status = NT_STATUS_UNSUCCESSFUL; goto done; @@ -4564,9 +4577,12 @@ int net_rpc_share(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - libnetapi_set_username(c->netapi_ctx, c->opt_user_name); - libnetapi_set_password(c->netapi_ctx, c->opt_password); - if (c->opt_kerberos) { + set_cmdline_auth_info_getpass(c->auth_info); + libnetapi_set_username(c->netapi_ctx, + get_cmdline_auth_info_username(c->auth_info)); + libnetapi_set_password(c->netapi_ctx, + get_cmdline_auth_info_password(c->auth_info)); + if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -4839,9 +4855,12 @@ int net_rpc_file(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - libnetapi_set_username(c->netapi_ctx, c->opt_user_name); - libnetapi_set_password(c->netapi_ctx, c->opt_password); - if (c->opt_kerberos) { + set_cmdline_auth_info_getpass(c->auth_info); + libnetapi_set_username(c->netapi_ctx, + get_cmdline_auth_info_username(c->auth_info)); + libnetapi_set_password(c->netapi_ctx, + get_cmdline_auth_info_password(c->auth_info)); + if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { libnetapi_set_use_kerberos(c->netapi_ctx); } @@ -5531,7 +5550,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc, c->opt_workgroup = smb_xstrdup(domain_name); }; - c->opt_user_name = acct_name; + set_cmdline_auth_info_username(c->auth_info, acct_name); /* find the domain controller */ if (!net_find_pdc(&server_ss, pdc_name, domain_name)) { @@ -5628,7 +5647,9 @@ static int rpc_trustdom_establish(struct net_context *c, int argc, * Store the password in secrets db */ - if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) { + if (!pdb_set_trusteddom_pw(domain_name, + get_cmdline_auth_info_password(c->auth_info), + domain_sid)) { DEBUG(0, ("Storing password for trusted domain failed.\n")); cli_shutdown(cli); talloc_destroy(mem_ctx); @@ -7190,9 +7211,12 @@ int net_rpc(struct net_context *c, int argc, const char **argv) if (status != 0) { return -1; } - libnetapi_set_username(c->netapi_ctx, c->opt_user_name); - libnetapi_set_password(c->netapi_ctx, c->opt_password); - if (c->opt_kerberos) { + set_cmdline_auth_info_getpass(c->auth_info); + libnetapi_set_username(c->netapi_ctx, + get_cmdline_auth_info_username(c->auth_info)); + libnetapi_set_password(c->netapi_ctx, + get_cmdline_auth_info_password(c->auth_info)); + if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { libnetapi_set_use_kerberos(c->netapi_ctx); } diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index ed0311317d..cae2491aed 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -58,7 +58,8 @@ NTSTATUS net_rpc_join_ok(struct net_context *c, const char *domain, if (sec == SEC_ADS) { /* Connect to IPC$ using machine account's credentials. We don't use anonymous connection here, as it may be denied by server's local policy. */ - net_use_machine_account(c); + set_cmdline_auth_info_use_machine_account(c->auth_info); + set_cmdline_auth_info_machine_account_creds(c->auth_info); } else { /* some servers (e.g. WinNT) don't accept machine-authenticated diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 6b23db74cb..bd5047c1ff 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -379,8 +379,8 @@ NTSTATUS rpc_vampire_keytab_internals(struct net_context *c, ctx->cli = pipe_hnd; ctx->ops = &libnet_samsync_keytab_ops; ctx->domain_name = domain_name; - ctx->username = c->opt_user_name; - ctx->password = c->opt_password; + ctx->username = get_cmdline_auth_info_username(c->auth_info); + ctx->password = get_cmdline_auth_info_password(c->auth_info); ctx->force_full_replication = c->opt_force_full_repl ? true : false; ctx->clean_old_entries = c->opt_clean_old_entries ? true : false; diff --git a/source3/utils/net_rpc_shell.c b/source3/utils/net_rpc_shell.c index 3aaed1ed18..dc13e91423 100644 --- a/source3/utils/net_rpc_shell.c +++ b/source3/utils/net_rpc_shell.c @@ -220,9 +220,12 @@ int net_rpc_shell(struct net_context *c, int argc, const char **argv) if (libnetapi_init(&c->netapi_ctx) != 0) { return -1; } - libnetapi_set_username(c->netapi_ctx, c->opt_user_name); - libnetapi_set_password(c->netapi_ctx, c->opt_password); - if (c->opt_kerberos) { + set_cmdline_auth_info_getpass(c->auth_info); + libnetapi_set_username(c->netapi_ctx, + get_cmdline_auth_info_username(c->auth_info)); + libnetapi_set_password(c->netapi_ctx, + get_cmdline_auth_info_password(c->auth_info)); + if (get_cmdline_auth_info_use_kerberos(c->auth_info)) { libnetapi_set_use_kerberos(c->netapi_ctx); } diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index 8bf9aac6f2..50f3c1db01 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -96,22 +96,22 @@ NTSTATUS connect_to_service(struct net_context *c, { NTSTATUS nt_status; int flags = 0; + struct user_auth_info *ai = c->auth_info; - c->opt_password = net_prompt_pass(c, c->opt_user_name); + set_cmdline_auth_info_getpass(ai); - if (c->opt_kerberos) { - flags |= CLI_FULL_CONNECTION_USE_KERBEROS; - } - - if (c->opt_kerberos && c->opt_password) { - flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; + if (get_cmdline_auth_info_use_kerberos(ai)) { + flags |= CLI_FULL_CONNECTION_USE_KERBEROS | + CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; } nt_status = cli_full_connection(cli_ctx, NULL, server_name, server_ss, c->opt_port, service_name, service_type, - c->opt_user_name, c->opt_workgroup, - c->opt_password, flags, Undefined, NULL); + get_cmdline_auth_info_username(ai), + c->opt_workgroup, + get_cmdline_auth_info_password(ai), + flags, Undefined, NULL); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, "Could not connect to server %s\n", server_name); @@ -131,10 +131,10 @@ NTSTATUS connect_to_service(struct net_context *c, return nt_status; } - if (c->smb_encrypt) { + if (get_cmdline_auth_info_smb_encrypt(ai)) { nt_status = cli_force_encryption(*cli_ctx, - c->opt_user_name, - c->opt_password, + get_cmdline_auth_info_username(ai), + get_cmdline_auth_info_password(ai), c->opt_workgroup); if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) { @@ -234,14 +234,12 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, { NTSTATUS nt_status; char *user_and_realm = NULL; + struct user_auth_info *ai = c->auth_info; /* FIXME: Should get existing kerberos ticket if possible. */ - c->opt_password = net_prompt_pass(c, c->opt_user_name); - if (!c->opt_password) { - return NT_STATUS_NO_MEMORY; - } + set_cmdline_auth_info_getpass(ai); - user_and_realm = get_user_and_realm(c->opt_user_name); + user_and_realm = get_user_and_realm(get_cmdline_auth_info_username(ai)); if (!user_and_realm) { return NT_STATUS_NO_MEMORY; } @@ -250,7 +248,7 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, server_ss, c->opt_port, "IPC$", "IPC", user_and_realm, c->opt_workgroup, - c->opt_password, + get_cmdline_auth_info_password(ai), CLI_FULL_CONNECTION_USE_KERBEROS, Undefined, NULL); @@ -261,10 +259,10 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c, return nt_status; } - if (c->smb_encrypt) { + if (get_cmdline_auth_info_smb_encrypt(ai)) { nt_status = cli_cm_force_encryption(*cli_ctx, user_and_realm, - c->opt_password, + get_cmdline_auth_info_password(ai), c->opt_workgroup, "IPC$"); if (!NT_STATUS_IS_OK(nt_status)) { @@ -328,50 +326,6 @@ NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst, return nt_status; } -/**************************************************************************** - Use the local machine account (krb) and password for this session. -****************************************************************************/ - -int net_use_krb_machine_account(struct net_context *c) -{ - char *user_name = NULL; - - if (!secrets_init()) { - d_fprintf(stderr, "ERROR: Unable to open secrets database\n"); - exit(1); - } - - c->opt_password = secrets_fetch_machine_password( - c->opt_target_workgroup, NULL, NULL); - if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) { - return -1; - } - c->opt_user_name = user_name; - return 0; -} - -/**************************************************************************** - Use the machine account name and password for this session. -****************************************************************************/ - -int net_use_machine_account(struct net_context *c) -{ - char *user_name = NULL; - - if (!secrets_init()) { - d_fprintf(stderr, "ERROR: Unable to open secrets database\n"); - exit(1); - } - - c->opt_password = secrets_fetch_machine_password( - c->opt_target_workgroup, NULL, NULL); - if (asprintf(&user_name, "%s$", global_myname()) == -1) { - return -1; - } - c->opt_user_name = user_name; - return 0; -} - bool net_find_server(struct net_context *c, const char *domain, unsigned flags, @@ -535,33 +489,6 @@ done: /**************************************************************************** ****************************************************************************/ -const char *net_prompt_pass(struct net_context *c, const char *user) -{ - char *prompt = NULL; - const char *pass = NULL; - - if (c->opt_password) { - return c->opt_password; - } - - if (c->opt_machine_pass) { - return NULL; - } - - if (c->opt_kerberos && !c->opt_user_specified) { - return NULL; - } - - if (asprintf(&prompt, "Enter %s's password:", user) == -1) { - return NULL; - } - - pass = getpass(prompt); - SAFE_FREE(prompt); - - return pass; -} - int net_run_function(struct net_context *c, int argc, const char **argv, const char *whoami, struct functable *table) { diff --git a/source3/winbindd/idmap_ldap.c b/source3/winbindd/idmap_ldap.c index 854fd21df8..88ece8c7de 100644 --- a/source3/winbindd/idmap_ldap.c +++ b/source3/winbindd/idmap_ldap.c @@ -1055,6 +1055,14 @@ again: TALLOC_FREE(sidstr); continue; } + + if (map->status == ID_MAPPED) { + DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. " + "overwriting mapping %u -> %s with %u -> %s\n", + (type == ID_TYPE_UID) ? "UID" : "GID", + id, sid_string_dbg(map->sid), id, sidstr)); + } + TALLOC_FREE(sidstr); /* mapped */ @@ -1249,8 +1257,6 @@ again: continue; } - TALLOC_FREE(sidstr); - /* now try to see if it is a uid, if not try with a gid * (gid is more common, but in case both uidNumber and * gidNumber are returned the SID is mapped to the uid @@ -1268,6 +1274,7 @@ again: if ( ! tmp) { /* no ids ?? */ DEBUG(5, ("no uidNumber, " "nor gidNumber attributes found\n")); + TALLOC_FREE(sidstr); continue; } @@ -1278,11 +1285,21 @@ again: DEBUG(5, ("Requested id (%u) out of range (%u - %u). " "Filtered!\n", id, ctx->filter_low_id, ctx->filter_high_id)); + TALLOC_FREE(sidstr); TALLOC_FREE(tmp); continue; } TALLOC_FREE(tmp); + if (map->status == ID_MAPPED) { + DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. " + "overwriting mapping %s -> %u with %s -> %u\n", + (type == ID_TYPE_UID) ? "UID" : "GID", + sidstr, map->xid.id, sidstr, id)); + } + + TALLOC_FREE(sidstr); + /* mapped */ map->xid.type = type; map->xid.id = id; diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 29793da22c..9d38a9ee0c 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1,21 +1,21 @@ -/* +/* Unix SMB/CIFS implementation. Winbind daemon for ntdom nss module Copyright (C) Tim Potter 2000-2001 Copyright (C) 2001 by Martin Pool <mbp@samba.org> - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 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 <http://www.gnu.org/licenses/>. */ @@ -47,7 +47,7 @@ static struct winbindd_domain *_domain_list = NULL; /** When was the last scan of trusted domains done? - + 0 == not ever */ @@ -72,7 +72,7 @@ void free_domain_list(void) while(domain) { struct winbindd_domain *next = domain->next; - + DLIST_REMOVE(_domain_list, domain); SAFE_FREE(domain); domain = next; @@ -131,28 +131,28 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const init_domain_list() and we'll get stuck in a loop. */ for (domain = _domain_list; domain; domain = domain->next) { if (strequal(domain_name, domain->name) || - strequal(domain_name, domain->alt_name)) + strequal(domain_name, domain->alt_name)) { - break; + break; } - if (alternative_name && *alternative_name) + if (alternative_name && *alternative_name) { if (strequal(alternative_name, domain->name) || - strequal(alternative_name, domain->alt_name)) + strequal(alternative_name, domain->alt_name)) { - break; + break; } } - if (sid) + if (sid) { if (is_null_sid(sid)) { - continue; + continue; } if (sid_equal(sid, &domain->sid)) { - break; + break; } } } @@ -164,8 +164,8 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const if ( sid_equal( &domain->sid, &global_sid_NULL ) ) sid_copy( &domain->sid, sid ); - return domain; - } + return domain; + } /* Create new domain entry */ @@ -230,7 +230,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const done: - DEBUG(2,("Added domain %s %s %s\n", + DEBUG(2,("Added domain %s %s %s\n", domain->name, domain->alt_name, &domain->sid?sid_string_dbg(&domain->sid):"")); @@ -243,8 +243,8 @@ done: struct trustdom_state { TALLOC_CTX *mem_ctx; - bool primary; - bool forest_root; + bool primary; + bool forest_root; struct winbindd_response *response; }; @@ -338,11 +338,11 @@ static void trustdom_recv(void *private_data, bool success) if (!string_to_sid(&sid, sidstr)) { /* Allow NULL sid for sibling domains */ if ( strcmp(sidstr,"S-0-0") == 0) { - sid_copy( &sid, &global_sid_NULL); - } else { + sid_copy( &sid, &global_sid_NULL); + } else { DEBUG(0, ("Got invalid trustdom response\n")); break; - } + } } /* use the real alt_name if we have one, else pass in NULL */ @@ -375,7 +375,7 @@ static void trustdom_recv(void *private_data, bool success) SAFE_FREE(response->extra_data.data); - /* + /* Cases to consider when scanning trusts: (a) we are calling from a child domain (primary && !forest_root) (b) we are calling from the root of the forest (primary && forest_root) @@ -412,7 +412,7 @@ static void rescan_forest_root_trusts( void ) { struct winbindd_tdc_domain *dom_list = NULL; size_t num_trusts = 0; - int i; + int i; /* The only transitive trusts supported by Windows 2003 AD are (a) Parent-Child, (b) Tree-Root, and (c) Forest. The @@ -426,8 +426,8 @@ static void rescan_forest_root_trusts( void ) for ( i=0; i<num_trusts; i++ ) { struct winbindd_domain *d = NULL; - /* Find the forest root. Don't necessarily trust - the domain_list() as our primary domain may not + /* Find the forest root. Don't necessarily trust + the domain_list() as our primary domain may not have been initialized. */ if ( !(dom_list[i].trust_flags & NETR_TRUST_FLAG_TREEROOT) ) { @@ -454,12 +454,12 @@ static void rescan_forest_root_trusts( void ) d->name, d->alt_name )); d->domain_flags = dom_list[i].trust_flags; - d->domain_type = dom_list[i].trust_type; - d->domain_trust_attribs = dom_list[i].trust_attribs; + d->domain_type = dom_list[i].trust_type; + d->domain_trust_attribs = dom_list[i].trust_attribs; add_trusted_domains( d ); - break; + break; } TALLOC_FREE( dom_list ); @@ -477,7 +477,7 @@ static void rescan_forest_trusts( void ) struct winbindd_domain *d = NULL; struct winbindd_tdc_domain *dom_list = NULL; size_t num_trusts = 0; - int i; + int i; /* The only transitive trusts supported by Windows 2003 AD are (a) Parent-Child, (b) Tree-Root, and (c) Forest. The @@ -498,7 +498,7 @@ static void rescan_forest_trusts( void ) /* ignore our primary and internal domains */ if ( d && (d->internal || d->primary ) ) - continue; + continue; if ( (flags & NETR_TRUST_FLAG_INBOUND) && (type == NETR_TRUST_TYPE_UPLEVEL) && @@ -526,7 +526,7 @@ static void rescan_forest_trusts( void ) TALLOC_FREE( dom_list ); - return; + return; } /********************************************************************* @@ -566,7 +566,7 @@ void rescan_trusted_domains( void ) last_trustdom_scan = now; - return; + return; } struct init_child_state { @@ -805,7 +805,7 @@ bool init_domain_list(void) void check_domain_trusted( const char *name, const DOM_SID *user_sid ) { - struct winbindd_domain *domain; + struct winbindd_domain *domain; DOM_SID dom_sid; uint32 rid; @@ -816,39 +816,39 @@ void check_domain_trusted( const char *name, const DOM_SID *user_sid ) domain = find_domain_from_name_noinit( name ); if ( domain ) - return; + return; - sid_copy( &dom_sid, user_sid ); + sid_copy( &dom_sid, user_sid ); if ( !sid_split_rid( &dom_sid, &rid ) ) return; /* add the newly discovered trusted domain */ - domain = add_trusted_domain( name, NULL, &cache_methods, + domain = add_trusted_domain( name, NULL, &cache_methods, &dom_sid); if ( !domain ) return; - /* assume this is a trust from a one-way transitive + /* assume this is a trust from a one-way transitive forest trust */ domain->active_directory = True; domain->domain_flags = NETR_TRUST_FLAG_OUTBOUND; domain->domain_type = NETR_TRUST_TYPE_UPLEVEL; domain->internal = False; - domain->online = True; + domain->online = True; setup_domain_child(domain, &domain->child); wcache_tdc_add_domain( domain ); - return; + return; } -/** - * Given a domain name, return the struct winbindd domain info for it +/** + * Given a domain name, return the struct winbindd domain info for it * * @note Do *not* pass lp_workgroup() to this function. domain_list * may modify it's value, and free that pointer. Instead, our local @@ -945,7 +945,7 @@ struct winbindd_domain *find_our_domain(void) struct winbindd_domain *find_root_domain(void) { - struct winbindd_domain *ours = find_our_domain(); + struct winbindd_domain *ours = find_our_domain(); if ( !ours ) return NULL; @@ -977,7 +977,7 @@ struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid) { /* SIDs in the S-1-22-{1,2} domain should be handled by our passdb */ - if ( sid_check_is_in_unix_groups(sid) || + if ( sid_check_is_in_unix_groups(sid) || sid_check_is_unix_groups(sid) || sid_check_is_in_unix_users(sid) || sid_check_is_unix_users(sid) ) @@ -994,7 +994,7 @@ struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid) if (IS_DC || is_internal_domain(sid) || is_in_internal_domain(sid)) { DEBUG(10, ("calling find_domain_from_sid\n")); return find_domain_from_sid(sid); - } + } /* On a member server a query for SID or name can always go to our * primary DC. */ @@ -1024,9 +1024,9 @@ struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name) bool winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx, enum winbindd_cmd orig_cmd, - struct winbindd_domain *domain, + struct winbindd_domain *domain, const char *domain_name, - const char *name, DOM_SID *sid, + const char *name, DOM_SID *sid, enum lsa_SidType *type) { NTSTATUS result; @@ -1121,7 +1121,7 @@ static bool assume_domain(const char *domain) if ( lp_winbind_use_default_domain() || lp_winbind_trusted_domains_only() ) return True; - } + } /* only left with a domain controller */ @@ -1144,7 +1144,7 @@ bool parse_domain_user(const char *domuser, fstring domain, fstring user) if ( assume_domain(lp_workgroup())) { fstrcpy(domain, lp_workgroup()); } else if ((p = strchr(domuser, '@')) != NULL) { - fstrcpy(domain, ""); + fstrcpy(domain, ""); } else { return False; } @@ -1225,7 +1225,7 @@ bool canonicalize_username(fstring username_inout, fstring domain, fstring user) If we are a PDC or BDC, and this is for our domain, do likewise. - Also, if omit DOMAIN if 'winbind trusted domains only = true', as the + Also, if omit DOMAIN if 'winbind trusted domains only = true', as the username is then unqualified in unix We always canonicalize as UPPERCASE DOMAIN, lowercase username. @@ -1277,12 +1277,12 @@ char *fill_domain_username_talloc(TALLOC_CTX *mem_ctx, * Winbindd socket accessor functions */ -const char *get_winbind_pipe_dir(void) +const char *get_winbind_pipe_dir(void) { return lp_parm_const_string(-1, "winbindd", "socket dir", WINBINDD_SOCKET_DIR); } -char *get_winbind_priv_pipe_dir(void) +char *get_winbind_priv_pipe_dir(void) { return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR); } @@ -1558,7 +1558,7 @@ bool winbindd_can_contact_domain(struct winbindd_domain *domain) * is running AD and we have no inbound trust. */ - if (!IS_DC && + if (!IS_DC && domain->active_directory && ((tdc->trust_flags & NETR_TRUST_FLAG_INBOUND) != NETR_TRUST_FLAG_INBOUND)) { @@ -1570,12 +1570,12 @@ bool winbindd_can_contact_domain(struct winbindd_domain *domain) /* Assume everything else is ok (probably not true but what can you do?) */ - ret = true; + ret = true; -done: +done: talloc_destroy(frame); - return ret; + return ret; } /********************************************************************* diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c index 48a488741f..19b223beba 100644 --- a/source4/torture/rpc/rpc.c +++ b/source4/torture/rpc/rpc.c @@ -409,6 +409,7 @@ NTSTATUS torture_rpc_init(void) torture_suite_add_suite(suite, torture_rpc_samr_accessmask(suite)); torture_suite_add_suite(suite, torture_rpc_samr_passwords_pwdlastset(suite)); torture_suite_add_suite(suite, torture_rpc_samr_user_privileges(suite)); + torture_suite_add_suite(suite, torture_rpc_samr_large_dc(suite)); torture_suite_add_suite(suite, torture_rpc_epmapper(suite)); torture_suite_add_suite(suite, torture_rpc_initshutdown(suite)); torture_suite_add_suite(suite, torture_rpc_oxidresolve(suite)); diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 692dddf73b..92ce66fef2 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -48,7 +48,10 @@ enum torture_samr_choice { TORTURE_SAMR_PASSWORDS_PWDLASTSET, TORTURE_SAMR_USER_ATTRIBUTES, TORTURE_SAMR_USER_PRIVILEGES, - TORTURE_SAMR_OTHER + TORTURE_SAMR_OTHER, + TORTURE_SAMR_MANY_ACCOUNTS, + TORTURE_SAMR_MANY_GROUPS, + TORTURE_SAMR_MANY_ALIASES }; static bool test_QueryUserInfo(struct dcerpc_pipe *p, @@ -3999,9 +4002,11 @@ static bool test_DeleteAlias(struct dcerpc_pipe *p, } static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx, - struct policy_handle *domain_handle, + struct policy_handle *domain_handle, + const char *alias_name, struct policy_handle *alias_handle, - const struct dom_sid *domain_sid) + const struct dom_sid *domain_sid, + bool test_alias) { NTSTATUS status; struct samr_CreateDomAlias r; @@ -4009,7 +4014,7 @@ static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx uint32_t rid; bool ret = true; - init_lsa_String(&name, TEST_ALIASNAME); + init_lsa_String(&name, alias_name); r.in.domain_handle = domain_handle; r.in.alias_name = &name; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -4043,6 +4048,10 @@ static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx return false; } + if (!test_alias) { + return ret; + } + if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) { ret = false; } @@ -4217,10 +4226,12 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *domain_handle, + const char *user_name, struct policy_handle *user_handle_out, struct dom_sid *domain_sid, enum torture_samr_choice which_ops, - struct cli_credentials *machine_credentials) + struct cli_credentials *machine_credentials, + bool test_user) { TALLOC_CTX *user_ctx; @@ -4239,7 +4250,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle user_handle; user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context"); - init_lsa_String(&name, TEST_ACCOUNT_NAME); + init_lsa_String(&name, user_name); r.in.domain_handle = domain_handle; r.in.account_name = &name; @@ -4269,11 +4280,21 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, } status = dcerpc_samr_CreateUser(p, user_ctx, &r); } + if (!NT_STATUS_IS_OK(status)) { talloc_free(user_ctx); printf("CreateUser failed - %s\n", nt_errstr(status)); return false; - } else { + } + + if (!test_user) { + if (user_handle_out) { + *user_handle_out = user_handle; + } + return ret; + } + + { q.in.user_handle = &user_handle; q.in.level = 16; q.out.info = &info; @@ -4869,8 +4890,9 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx, return ret; } -static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx, - struct policy_handle *handle) +static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle) { NTSTATUS status = STATUS_MORE_ENTRIES; struct samr_EnumDomainUsers r; @@ -4998,9 +5020,9 @@ static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_con return true; } -static bool test_EnumDomainGroups(struct dcerpc_pipe *p, - struct torture_context *tctx, - struct policy_handle *handle) +static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle) { NTSTATUS status; struct samr_EnumDomainGroups r; @@ -5038,9 +5060,9 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, return ret; } -static bool test_EnumDomainAliases(struct dcerpc_pipe *p, - struct torture_context *tctx, - struct policy_handle *handle) +static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle) { NTSTATUS status; struct samr_EnumDomainAliases r; @@ -5931,10 +5953,12 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t static bool test_CreateDomainGroup(struct dcerpc_pipe *p, - struct torture_context *tctx, + struct torture_context *tctx, struct policy_handle *domain_handle, + const char *group_name, struct policy_handle *group_handle, - struct dom_sid *domain_sid) + struct dom_sid *domain_sid, + bool test_group) { NTSTATUS status; struct samr_CreateDomainGroup r; @@ -5942,7 +5966,7 @@ static bool test_CreateDomainGroup(struct dcerpc_pipe *p, struct lsa_String name; bool ret = true; - init_lsa_String(&name, TEST_GROUPNAME); + init_lsa_String(&name, group_name); r.in.domain_handle = domain_handle; r.in.name = &name; @@ -5984,6 +6008,10 @@ static bool test_CreateDomainGroup(struct dcerpc_pipe *p, } torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup"); + if (!test_group) { + return ret; + } + if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) { printf("CreateDomainGroup failed - %s\n", nt_errstr(status)); ret = false; @@ -6016,7 +6044,235 @@ static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, return true; } +static bool test_EnumDomainUsers(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *domain_handle, + uint32_t *total_num_entries_p) +{ + NTSTATUS status; + struct samr_EnumDomainUsers r; + uint32_t resume_handle = 0; + uint32_t num_entries = 0; + uint32_t total_num_entries = 0; + struct samr_SamArray *sam; + + r.in.domain_handle = domain_handle; + r.in.acct_flags = ACB_NORMAL; + r.in.max_size = (uint32_t)-1; + r.in.resume_handle = &resume_handle; + + r.out.sam = &sam; + r.out.num_entries = &num_entries; + r.out.resume_handle = &resume_handle; + + printf("Testing EnumDomainUsers\n"); + + do { + status = dcerpc_samr_EnumDomainUsers(p, tctx, &r); + if (NT_STATUS_IS_ERR(status)) { + torture_assert_ntstatus_ok(tctx, status, + "failed to enumerate users"); + } + + total_num_entries += num_entries; + } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); + + if (total_num_entries_p) { + *total_num_entries_p = total_num_entries; + } + + return true; +} + +static bool test_EnumDomainGroups(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *domain_handle, + uint32_t *total_num_entries_p) +{ + NTSTATUS status; + struct samr_EnumDomainGroups r; + uint32_t resume_handle = 0; + uint32_t num_entries = 0; + uint32_t total_num_entries = 0; + struct samr_SamArray *sam; + + r.in.domain_handle = domain_handle; + r.in.max_size = (uint32_t)-1; + r.in.resume_handle = &resume_handle; + + r.out.sam = &sam; + r.out.num_entries = &num_entries; + r.out.resume_handle = &resume_handle; + + printf("Testing EnumDomainGroups\n"); + + do { + status = dcerpc_samr_EnumDomainGroups(p, tctx, &r); + if (NT_STATUS_IS_ERR(status)) { + torture_assert_ntstatus_ok(tctx, status, + "failed to enumerate groups"); + } + + total_num_entries += num_entries; + } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); + + if (total_num_entries_p) { + *total_num_entries_p = total_num_entries; + } + + return true; +} + +static bool test_EnumDomainAliases(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *domain_handle, + uint32_t *total_num_entries_p) +{ + NTSTATUS status; + struct samr_EnumDomainAliases r; + uint32_t resume_handle = 0; + uint32_t num_entries = 0; + uint32_t total_num_entries = 0; + struct samr_SamArray *sam; + + r.in.domain_handle = domain_handle; + r.in.max_size = (uint32_t)-1; + r.in.resume_handle = &resume_handle; + + r.out.sam = &sam; + r.out.num_entries = &num_entries; + r.out.resume_handle = &resume_handle; + + printf("Testing EnumDomainAliases\n"); + + do { + status = dcerpc_samr_EnumDomainAliases(p, tctx, &r); + if (NT_STATUS_IS_ERR(status)) { + torture_assert_ntstatus_ok(tctx, status, + "failed to enumerate aliases"); + } + + total_num_entries += num_entries; + } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); + if (total_num_entries_p) { + *total_num_entries_p = total_num_entries; + } + + return true; +} + +static bool test_ManyObjects(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *domain_handle, + struct dom_sid *domain_sid, + enum torture_samr_choice which_ops) +{ + uint32_t num_total = 1500; + uint32_t num_enum = 0; + uint32_t num_disp = 0; + uint32_t num_created = 0; + uint32_t num_anounced = 0; + bool ret = true; + NTSTATUS status; + uint32_t i; + + /* query */ + + { + struct samr_QueryDomainInfo2 r; + union samr_DomainInfo *info; + r.in.domain_handle = domain_handle; + r.in.level = 2; + r.out.info = &info; + + status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, + "failed to query domain info"); + + switch (which_ops) { + case TORTURE_SAMR_MANY_ACCOUNTS: + num_anounced = info->general.num_users; + break; + case TORTURE_SAMR_MANY_GROUPS: + num_anounced = info->general.num_groups; + break; + case TORTURE_SAMR_MANY_ALIASES: + num_anounced = info->general.num_aliases; + break; + default: + return false; + } + } + + /* create */ + + for (i=0; i < num_total; i++) { + + struct policy_handle handle; + const char *name = NULL; + + ZERO_STRUCT(handle); + + switch (which_ops) { + case TORTURE_SAMR_MANY_ACCOUNTS: + name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i); + ret &= test_CreateUser(p, tctx, domain_handle, name, &handle, domain_sid, 0, NULL, false); + break; + case TORTURE_SAMR_MANY_GROUPS: + name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i); + ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handle, domain_sid, false); + break; + case TORTURE_SAMR_MANY_ALIASES: + name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i); + ret &= test_CreateAlias(p, tctx, domain_handle, name, &handle, domain_sid, false); + break; + default: + return false; + } + if (!policy_handle_empty(&handle)) { + ret &= test_samr_handle_Close(p, tctx, &handle); + num_created++; + } + } + + /* enum */ + + switch (which_ops) { + case TORTURE_SAMR_MANY_ACCOUNTS: + ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum); + break; + case TORTURE_SAMR_MANY_GROUPS: + ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum); + break; + case TORTURE_SAMR_MANY_ALIASES: + ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum); + break; + default: + return false; + } + + torture_assert_int_equal(tctx, num_enum, num_anounced + num_created, + "unexpected number of results returned in enum call"); +#if 0 + /* TODO: dispinfo */ + + switch (which_ops) { + case TORTURE_SAMR_MANY_ACCOUNTS: + break; + case TORTURE_SAMR_MANY_GROUPS: + break; + case TORTURE_SAMR_MANY_ALIASES: + break; + default: + return false; + } + + torture_assert_int_equal(tctx, num_disp, num_anounced + num_created, + "unexpected number of results returned in dispinfo call"); +#endif + return ret; +} static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *handle); @@ -6060,7 +6316,7 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, if (!torture_setting_bool(tctx, "samba3", false)) { ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL); } - ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL); + ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true); /* This test needs 'complex' users to validate */ ret &= test_QueryDisplayInfo(p, tctx, &domain_handle); if (!ret) { @@ -6071,13 +6327,18 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, if (!torture_setting_bool(tctx, "samba3", false)) { ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials); } - ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials); + ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true); if (!ret) { printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid)); } break; + case TORTURE_SAMR_MANY_ACCOUNTS: + case TORTURE_SAMR_MANY_GROUPS: + case TORTURE_SAMR_MANY_ALIASES: + ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops); + break; case TORTURE_SAMR_OTHER: - ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, NULL); + ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true); if (!ret) { printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid)); } @@ -6085,14 +6346,14 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, ret &= test_QuerySecurity(p, tctx, &domain_handle); } ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle); - ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid); - ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid); + ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true); + ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true); ret &= test_QueryDomainInfo(p, tctx, &domain_handle); ret &= test_QueryDomainInfo2(p, tctx, &domain_handle); - ret &= test_EnumDomainUsers(p, tctx, &domain_handle); + ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle); ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle); - ret &= test_EnumDomainGroups(p, tctx, &domain_handle); - ret &= test_EnumDomainAliases(p, tctx, &domain_handle); + ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle); + ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle); ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle); ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle); ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle); @@ -6504,3 +6765,97 @@ struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx) return suite; } + +static bool torture_rpc_samr_many_accounts(struct torture_context *torture, + struct dcerpc_pipe *p2, + struct cli_credentials *machine_credentials) +{ + NTSTATUS status; + struct dcerpc_pipe *p; + bool ret = true; + struct policy_handle handle; + + status = torture_rpc_connection(torture, &p, &ndr_table_samr); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + + ret &= test_Connect(p, torture, &handle); + + ret &= test_EnumDomains(p, torture, &handle, + TORTURE_SAMR_MANY_ACCOUNTS, + machine_credentials); + + ret &= test_samr_handle_Close(p, torture, &handle); + + return ret; +} + +static bool torture_rpc_samr_many_groups(struct torture_context *torture, + struct dcerpc_pipe *p2, + struct cli_credentials *machine_credentials) +{ + NTSTATUS status; + struct dcerpc_pipe *p; + bool ret = true; + struct policy_handle handle; + + status = torture_rpc_connection(torture, &p, &ndr_table_samr); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + + ret &= test_Connect(p, torture, &handle); + + ret &= test_EnumDomains(p, torture, &handle, + TORTURE_SAMR_MANY_GROUPS, + machine_credentials); + + ret &= test_samr_handle_Close(p, torture, &handle); + + return ret; +} + +static bool torture_rpc_samr_many_aliases(struct torture_context *torture, + struct dcerpc_pipe *p2, + struct cli_credentials *machine_credentials) +{ + NTSTATUS status; + struct dcerpc_pipe *p; + bool ret = true; + struct policy_handle handle; + + status = torture_rpc_connection(torture, &p, &ndr_table_samr); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + + ret &= test_Connect(p, torture, &handle); + + ret &= test_EnumDomains(p, torture, &handle, + TORTURE_SAMR_MANY_ALIASES, + machine_credentials); + + ret &= test_samr_handle_Close(p, torture, &handle); + + return ret; +} + +struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC"); + struct torture_rpc_tcase *tcase; + + tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr", + &ndr_table_samr, + TEST_ACCOUNT_NAME); + + torture_rpc_tcase_add_test_creds(tcase, "many_aliases", + torture_rpc_samr_many_aliases); + torture_rpc_tcase_add_test_creds(tcase, "many_groups", + torture_rpc_samr_many_groups); + torture_rpc_tcase_add_test_creds(tcase, "many_accounts", + torture_rpc_samr_many_accounts); + + return suite; +} diff --git a/source4/torture/smbiconv.c b/source4/torture/smbiconv.c index 4eece66bdf..173f37175b 100644 --- a/source4/torture/smbiconv.c +++ b/source4/torture/smbiconv.c @@ -208,6 +208,7 @@ int main(int argc, char *argv[]) cd = smb_iconv_open_ex(tctx, to, from, lp_parm_bool(tctx->lp_ctx, NULL, "iconv", "native", true)); if((int)cd == -1) { DEBUG(0,("unable to find from or to encoding, exiting...\n")); + if (out != stdout) fclose(out); return 1; } |