diff options
Diffstat (limited to 'source3/utils')
-rw-r--r-- | source3/utils/net.c | 70 | ||||
-rw-r--r-- | source3/utils/net.h | 5 | ||||
-rw-r--r-- | source3/utils/net_ads.c | 269 | ||||
-rw-r--r-- | source3/utils/net_help.c | 71 | ||||
-rw-r--r-- | source3/utils/net_lookup.c | 173 | ||||
-rw-r--r-- | source3/utils/net_rap.c | 53 | ||||
-rw-r--r-- | source3/utils/net_rpc.c | 671 | ||||
-rw-r--r-- | source3/utils/net_rpc_join.c | 10 | ||||
-rw-r--r-- | source3/utils/net_time.c | 6 | ||||
-rw-r--r-- | source3/utils/nmblookup.c | 34 | ||||
-rw-r--r-- | source3/utils/pdbedit.c | 538 | ||||
-rw-r--r-- | source3/utils/smbcacls.c | 126 | ||||
-rw-r--r-- | source3/utils/smbcontrol.c | 157 | ||||
-rw-r--r-- | source3/utils/smbgroupedit.c | 18 | ||||
-rw-r--r-- | source3/utils/smbpasswd.c | 105 | ||||
-rw-r--r-- | source3/utils/smbtree.c | 85 | ||||
-rw-r--r-- | source3/utils/status.c | 18 | ||||
-rw-r--r-- | source3/utils/testparm.c | 277 |
18 files changed, 1786 insertions, 900 deletions
diff --git a/source3/utils/net.c b/source3/utils/net.c index b81e37c0af..d34ac21f39 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -72,11 +72,13 @@ int opt_flags = -1; int opt_jobid = 0; int opt_timeout = 0; char *opt_target_workgroup = NULL; +static int opt_machine_pass = 0; BOOL opt_have_ip = False; struct in_addr opt_dest_ip; extern pstring global_myname; +extern BOOL AllowDebugChange; /* run a function from a function table. If not found then @@ -119,7 +121,7 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip, server_ip, opt_port, "IPC$", "IPC", opt_user_name, opt_workgroup, - opt_password, strlen(opt_password)); + opt_password, 0); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -279,8 +281,6 @@ struct cli_state *net_make_ipc_connection(unsigned flags) return cli; } - - static int net_user(int argc, const char **argv) { if (net_ads_check() == 0) @@ -293,6 +293,16 @@ static int net_user(int argc, const char **argv) return net_rap_user(argc, argv); } +static int net_group(int argc, const char **argv) +{ + if (net_ads_check() == 0) + return net_ads_group(argc, argv); + + if (argc == 0 && net_rpc_check(NET_FLAGS_PDC)) + return net_rpc_group(argc, argv); + + return net_rap_group(argc, argv); +} static int net_join(int argc, const char **argv) { @@ -305,6 +315,20 @@ static int net_join(int argc, const char **argv) return net_rpc_join(argc, argv); } +static int net_share(int argc, const char **argv) +{ + if (net_rpc_check(0)) + return net_rpc_share(argc, argv); + return net_rap_share(argc, argv); +} + +static int net_file(int argc, const char **argv) +{ + if (net_rpc_check(0)) + return net_rpc_file(argc, argv); + return net_rap_file(argc, argv); +} + /* main function table */ static struct functable net_func[] = { {"RPC", net_rpc}, @@ -312,14 +336,14 @@ static struct functable net_func[] = { {"ADS", net_ads}, /* eventually these should auto-choose the transport ... */ - {"FILE", net_rap_file}, - {"SHARE", net_rap_share}, + {"FILE", net_file}, + {"SHARE", net_share}, {"SESSION", net_rap_session}, {"SERVER", net_rap_server}, {"DOMAIN", net_rap_domain}, {"PRINTQ", net_rap_printq}, {"USER", net_user}, - {"GROUP", net_rap_group}, + {"GROUP", net_group}, {"VALIDATE", net_rap_validate}, {"GROUPMEMBER", net_rap_groupmember}, {"ADMIN", net_rap_admin}, @@ -346,7 +370,7 @@ static struct functable net_func[] = { const char ** argv_new; poptContext pc; static char *servicesf = dyn_CONFIGFILE; - static int debuglevel = 0; + static char *debuglevel = NULL; struct poptOption long_options[] = { {"help", 'h', POPT_ARG_NONE, 0, 'h'}, @@ -357,8 +381,8 @@ static struct functable net_func[] = { {"port", 'p', POPT_ARG_INT, &opt_port}, {"myname", 'n', POPT_ARG_STRING, &opt_requester_name}, {"conf", 's', POPT_ARG_STRING, &servicesf}, - {"debug", 'd', POPT_ARG_INT, &debuglevel}, - {"debuglevel", 'd', POPT_ARG_INT, &debuglevel}, + {"debug", 'd', POPT_ARG_STRING, &debuglevel}, + {"debuglevel", 'd', POPT_ARG_STRING, &debuglevel}, {"server", 'S', POPT_ARG_STRING, &opt_host}, {"comment", 'C', POPT_ARG_STRING, &opt_comment}, {"maxusers", 'M', POPT_ARG_INT, &opt_maxusers}, @@ -368,6 +392,7 @@ static struct functable net_func[] = { {"reboot", 'r', POPT_ARG_NONE, &opt_reboot}, {"force", 'f', POPT_ARG_NONE, &opt_force}, {"timeout", 't', POPT_ARG_INT, &opt_timeout}, + {"machine-pass",'P', POPT_ARG_NONE, &opt_machine_pass}, { 0, 0, 0, 0} }; @@ -403,12 +428,16 @@ static struct functable net_func[] = { default: d_printf("\nInvalid option %c (%d)\n", (char)opt, opt); net_help(argc, argv); + exit(1); } } - lp_load(servicesf,True,False,False); + if (debuglevel) { + debug_parse_levels(debuglevel); + AllowDebugChange = False; + } - DEBUGLEVEL = debuglevel; + lp_load(servicesf,True,False,False); argv_new = (const char **)poptGetArgs(pc); @@ -419,7 +448,7 @@ static struct functable net_func[] = { break; } } - + if (!opt_requester_name) { static fstring myname; get_myname(myname); @@ -451,6 +480,23 @@ static struct functable net_func[] = { load_interfaces(); + if (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 */ + + if (!secrets_init()) { + d_printf("ERROR: Unable to open secrets database\n"); + exit(1); + } + + asprintf(&opt_user_name,"%s$", global_myname); + opt_password = secrets_fetch_machine_password(); + if (!opt_password) { + d_printf("ERROR: Unable to fetch machine password\n"); + exit(1); + } + } + rc = net_run_function(argc_new-1, argv_new+1, net_func, net_help); DEBUG(2,("return code = %d\n", rc)); diff --git a/source3/utils/net.h b/source3/utils/net.h index af6f153f7b..86bdf2082e 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -16,6 +16,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "../utils/net_proto.h" #define NET_FLAGS_MASTER 1 #define NET_FLAGS_DMB 2 @@ -49,3 +51,6 @@ extern char *opt_host; extern char *opt_user_name; extern char *opt_password; extern BOOL opt_user_specified; + +extern const char *share_type[]; + diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 68fa89ea35..fa3eac6bd3 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -33,20 +33,22 @@ int net_ads_usage(int argc, const char **argv) "\nnet ads leave"\ "\n\tremoves the local machine from a ADS realm\n"\ "\nnet ads user"\ -"\n\tlist users in the realm\n"\ +"\n\tlist, add, or delete users in the realm\n"\ "\nnet ads group"\ -"\n\tlist groups in the realm\n"\ +"\n\tlist, add, or delete groups in the realm\n"\ "\nnet ads info"\ "\n\tshows some info on the server\n"\ "\nnet ads status"\ "\n\tdump the machine account details to stdout\n" "\nnet ads password <username@realm> -Uadmin_username@realm%%admin_pass"\ -"\n\tchange a user's password using an admin account" -"\n\t(note: use realm in UPPERCASE)\n" -"\nnet ads chostpass" -"\n\tchange the trust account password of this machine in the AD tree\n" -"\nnet ads printer [info | publish | remove] <printername> <servername>" -"\n\t lookup, add, or remove directory entry for a printer\n" +"\n\tchange a user's password using an admin account"\ +"\n\t(note: use realm in UPPERCASE)\n"\ +"\nnet ads chostpass"\ +"\n\tchange the trust account password of this machine in the AD tree\n"\ +"\nnet ads printer [info | publish | remove] <printername> <servername>"\ +"\n\t lookup, add, or remove directory entry for a printer\n"\ +"\nnet ads search"\ +"\n\tperform a raw LDAP search and dump the results\n" ); return -1; } @@ -56,7 +58,7 @@ static int net_ads_info(int argc, const char **argv) { ADS_STRUCT *ads; - ads = ads_init(NULL, opt_host, NULL, NULL); + ads = ads_init(NULL, NULL, opt_host, NULL, NULL); ads_connect(ads); if (!ads) { @@ -81,7 +83,7 @@ static ADS_STRUCT *ads_startup(void) BOOL need_password = False; BOOL second_time = False; - ads = ads_init(NULL, opt_host, NULL, NULL); + ads = ads_init(NULL, NULL, opt_host, NULL, NULL); if (!opt_user_name) { opt_user_name = "administrator"; @@ -135,27 +137,30 @@ int net_ads_check(void) } -static void usergrp_display(char *field, void **values, void *data_area) +static BOOL usergrp_display(char *field, void **values, void *data_area) { char **disp_fields = (char **) data_area; if (!field) { /* must be end of record */ if (!strchr_m(disp_fields[0], '$')) { if (disp_fields[1]) - printf("%-21.21s %-50.50s\n", + d_printf("%-21.21s %-50.50s\n", disp_fields[0], disp_fields[1]); else - printf("%-21.21s\n", disp_fields[0]); + d_printf("%s\n", disp_fields[0]); } SAFE_FREE(disp_fields[0]); SAFE_FREE(disp_fields[1]); - return; + return True; } + if (!values) /* must be new field, indicate string field */ + return True; if (StrCaseCmp(field, "sAMAccountName") == 0) { - disp_fields[0] = strdup(((struct berval *) values[0])->bv_val); + disp_fields[0] = strdup((char *) values[0]); } if (StrCaseCmp(field, "description") == 0) - disp_fields[1] = strdup(((struct berval *) values[0])->bv_val); + disp_fields[1] = strdup((char *) values[0]); + return True; /* always strings here */ } static int net_ads_user_usage(int argc, const char **argv) @@ -167,6 +172,7 @@ static int ads_user_add(int argc, const char **argv) { ADS_STRUCT *ads; ADS_STATUS status; + char *upn, *userdn; void *res=NULL; int rc = -1; @@ -183,18 +189,43 @@ static int ads_user_add(int argc, const char **argv) if (ads_count_replies(ads, res)) { d_printf("ads_user_add: User %s already exists\n", argv[0]); - ads_msgfree(ads, res); goto done; } status = ads_add_user_acct(ads, argv[0], opt_comment); + if (!ADS_ERR_OK(status)) { + d_printf("Could not add user %s: %s\n", argv[0], + ads_errstr(status)); + goto done; + } + + /* if no password is to be set, we're done */ + if (argc == 1) { + d_printf("User %s added\n", argv[0]); + rc = 0; + goto done; + } + + /* try setting the password */ + asprintf(&upn, "%s@%s", argv[0], ads->realm); + status = krb5_set_password(ads->kdc_server, upn, argv[1]); + safe_free(upn); if (ADS_ERR_OK(status)) { d_printf("User %s added\n", argv[0]); rc = 0; - } else { - d_printf("Could not add user %s: %s\n", argv[0], - ads_errstr(status)); + goto done; + } + + /* password didn't set, delete account */ + d_printf("Could not add user %s. Error setting password %s\n", + argv[0], ads_errstr(status)); + ads_msgfree(ads, res); + status=ads_find_user_acct(ads, &res, argv[0]); + if (ADS_ERR_OK(status)) { + userdn = ads_get_dn(ads, res); + ads_del_dn(ads, userdn); + ads_memfree(ads, userdn); } done: @@ -233,7 +264,7 @@ static int ads_user_info(int argc, const char **argv) char **groupname; for (i=0;grouplist[i];i++) { groupname = ldap_explode_dn(grouplist[i], 1); - printf("%s\n", groupname[0]); + d_printf("%s\n", groupname[0]); ldap_value_free(groupname); } ldap_value_free(grouplist); @@ -308,26 +339,111 @@ int net_ads_user(int argc, const char **argv) return net_run_function(argc, argv, func, net_ads_user_usage); } -static int net_ads_group(int argc, const char **argv) +static int net_ads_group_usage(int argc, const char **argv) +{ + return net_help_group(argc, argv); +} + +static int ads_group_add(int argc, const char **argv) +{ + ADS_STRUCT *ads; + ADS_STATUS status; + void *res=NULL; + int rc = -1; + + if (argc < 1) return net_ads_group_usage(argc, argv); + + if (!(ads = ads_startup())) return -1; + + status = ads_find_user_acct(ads, &res, argv[0]); + + if (!ADS_ERR_OK(status)) { + d_printf("ads_group_add: %s\n", ads_errstr(status)); + goto done; + } + + if (ads_count_replies(ads, res)) { + d_printf("ads_group_add: Group %s already exists\n", argv[0]); + ads_msgfree(ads, res); + goto done; + } + + status = ads_add_group_acct(ads, argv[0], opt_comment); + + if (ADS_ERR_OK(status)) { + d_printf("Group %s added\n", argv[0]); + rc = 0; + } else { + d_printf("Could not add group %s: %s\n", argv[0], + ads_errstr(status)); + } + + done: + if (res) + ads_msgfree(ads, res); + ads_destroy(&ads); + return rc; +} + +static int ads_group_delete(int argc, const char **argv) +{ + ADS_STRUCT *ads; + ADS_STATUS rc; + void *res; + char *groupdn; + + if (argc < 1) return net_ads_group_usage(argc, argv); + + if (!(ads = ads_startup())) return -1; + + rc = ads_find_user_acct(ads, &res, argv[0]); + if (!ADS_ERR_OK(rc)) { + DEBUG(0, ("Group %s does not exist\n", argv[0])); + return -1; + } + groupdn = ads_get_dn(ads, res); + ads_msgfree(ads, res); + rc = ads_del_dn(ads, groupdn); + ads_memfree(ads, groupdn); + if (!ADS_ERR_OK(rc)) { + d_printf("Group %s deleted\n", argv[0]); + return 0; + } + d_printf("Error deleting group %s: %s\n", argv[0], + ads_errstr(rc)); + return -1; +} + +int net_ads_group(int argc, const char **argv) { + struct functable func[] = { + {"ADD", ads_group_add}, + {"DELETE", ads_group_delete}, + {NULL, NULL} + }; ADS_STRUCT *ads; ADS_STATUS rc; const char *shortattrs[] = {"sAMAccountName", NULL}; const char *longattrs[] = {"sAMAccountName", "description", NULL}; char *disp_fields[2] = {NULL, NULL}; - if (!(ads = ads_startup())) return -1; + if (argc == 0) { + if (!(ads = ads_startup())) return -1; - if (opt_long_list_entries) - d_printf("\nGroup name Comment"\ - "\n-----------------------------\n"); - rc = ads_do_search_all_fn(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, - "(objectclass=group)", opt_long_list_entries - ? longattrs : shortattrs, usergrp_display, - disp_fields); + if (opt_long_list_entries) + d_printf("\nGroup name Comment"\ + "\n-----------------------------\n"); + rc = ads_do_search_all_fn(ads, ads->bind_path, + LDAP_SCOPE_SUBTREE, + "(objectclass=group)", + opt_long_list_entries ? longattrs : + shortattrs, usergrp_display, + disp_fields); - ads_destroy(&ads); - return 0; + ads_destroy(&ads); + return 0; + } + return net_run_function(argc, argv, func, net_ads_group_usage); } static int net_ads_status(int argc, const char **argv) @@ -485,7 +601,7 @@ static int net_ads_printer_info(int argc, const char **argv) { ADS_STRUCT *ads; ADS_STATUS rc; - char *servername, *printername; + const char *servername, *printername; extern pstring global_myname; void *res = NULL; @@ -521,6 +637,11 @@ static int net_ads_printer_info(int argc, const char **argv) return 0; } +void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len) +{ + return; +} + static int net_ads_printer_publish(int argc, const char **argv) { ADS_STRUCT *ads; @@ -528,6 +649,7 @@ static int net_ads_printer_publish(int argc, const char **argv) char *uncname, *servername; ADS_PRINTER_ENTRY prt; extern pstring global_myname; + char *ports[2] = {"Samba", NULL}; /* these const strings are only here as an example. The attributes @@ -536,7 +658,6 @@ static int net_ads_printer_publish(int argc, const char **argv) const char *bins[] = {"Tray 21", NULL}; const char *media[] = {"Letter", NULL}; const char *orients[] = {"PORTRAIT", NULL}; - const char *ports[] = {"Samba", NULL}; if (!(ads = ads_startup())) return -1; @@ -545,6 +666,9 @@ static int net_ads_printer_publish(int argc, const char **argv) memset(&prt, 0, sizeof(ADS_PRINTER_ENTRY)); + /* we don't sue the servername or unc name provided by + get_a_printer, because the server name might be + localhost or an ip address */ prt.printerName = argv[0]; asprintf(&servername, "%s.%s", global_myname, ads->realm); prt.serverName = servername; @@ -557,7 +681,7 @@ static int net_ads_printer_publish(int argc, const char **argv) prt.printOrientationsSupported = (char **) orients; prt.portName = (char **) ports; prt.printSpooling = "PrintAfterSpooled"; - + rc = ads_add_printer(ads, &prt); if (!ADS_ERR_OK(rc)) { d_printf("ads_publish_printer: %s\n", ads_errstr(rc)); @@ -650,7 +774,7 @@ static int net_ads_password(int argc, const char **argv) /* use the realm so we can eventually change passwords for users in realms other than default */ - if (!(ads = ads_init(realm, NULL, NULL, NULL))) return -1; + if (!(ads = ads_init(realm, NULL, NULL, NULL, NULL))) return -1; asprintf(&prompt, "Enter new password for %s:", argv[0]); @@ -681,8 +805,7 @@ static int net_ads_change_localhost_pass(int argc, const char **argv) char *hostname; ADS_STATUS ret; - - if (!(ads = ads_init(NULL, NULL, NULL, NULL))) return -1; + if (!(ads = ads_init_simple())) return -1; hostname = strdup(global_myname); strlower(hostname); @@ -706,19 +829,79 @@ static int net_ads_change_localhost_pass(int argc, const char **argv) return 0; } +/* + help for net ads search +*/ +static int net_ads_search_usage(int argc, const char **argv) +{ + d_printf( + "\nnet ads search <expression> <attributes...>\n"\ + "\nperform a raw LDAP search on a ADS server and dump the results\n"\ + "The expression is a standard LDAP search expression, and the\n"\ + "attributes are a list of LDAP fields to show in the results\n\n"\ + "Example: net ads search '(objectCategory=group)' sAMAccountName\n\n" + ); + net_common_flags_usage(argc, argv); + return -1; +} + + +/* + general ADS search function. Useful in diagnosing problems in ADS +*/ +static int net_ads_search(int argc, const char **argv) +{ + ADS_STRUCT *ads; + ADS_STATUS rc; + const char *exp; + const char **attrs; + void *res = NULL; + + if (argc < 1) { + return net_ads_search_usage(argc, argv); + } + + if (!(ads = ads_startup())) { + return -1; + } + + exp = argv[0]; + attrs = (argv + 1); + + rc = ads_do_search_all(ads, ads->bind_path, + LDAP_SCOPE_SUBTREE, + exp, attrs, &res); + if (!ADS_ERR_OK(rc)) { + d_printf("search failed: %s\n", ads_errstr(rc)); + return -1; + } + + d_printf("Got %d replies\n\n", ads_count_replies(ads, res)); + + /* dump the results */ + ads_dump(ads, res); + + ads_msgfree(ads, res); + ads_destroy(&ads); + + return 0; +} + + int net_ads_help(int argc, const char **argv) { struct functable func[] = { {"USER", net_ads_user_usage}, + {"GROUP", net_ads_group_usage}, + {"PRINTER", net_ads_printer_usage}, + {"SEARCH", net_ads_search_usage}, #if 0 {"INFO", net_ads_info}, {"JOIN", net_ads_join}, {"LEAVE", net_ads_leave}, {"STATUS", net_ads_status}, - {"GROUP", net_ads_group}, {"PASSWORD", net_ads_password}, {"CHOSTPASS", net_ads_change_localhost_pass}, - {"PRINTER", net_ads_printer}, #endif {NULL, NULL} }; @@ -738,6 +921,7 @@ int net_ads(int argc, const char **argv) {"PASSWORD", net_ads_password}, {"CHOSTPASS", net_ads_change_localhost_pass}, {"PRINTER", net_ads_printer}, + {"SEARCH", net_ads_search}, {"HELP", net_ads_help}, {NULL, NULL} }; @@ -773,6 +957,11 @@ int net_ads_user(int argc, const char **argv) return net_ads_noads(); } +int net_ads_group(int argc, const char **argv) +{ + return net_ads_noads(); +} + /* this one shouldn't display a message */ int net_ads_check(void) { diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index 21af8a4fd9..ab3eac4b43 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "../utils/net.h" int net_common_methods_usage(int argc, const char**argv) { @@ -63,12 +64,12 @@ static int help_usage(int argc, const char **argv) int net_help_user(int argc, const char **argv) { - d_printf("\nnet [method] user [misc. options] [targets]\n\tList users\n"); - d_printf("\nnet [method] user DELETE <name> [misc. options] [targets]"\ + d_printf("\nnet <method> user [misc. options] [targets]\n\tList users\n"); + d_printf("\nnet <method> user DELETE <name> [misc. options] [targets]"\ "\n\tDelete specified user\n"); - d_printf("\nnet [method] user INFO <name> [misc. options] [targets]"\ + d_printf("\nnet <method> user INFO <name> [misc. options] [targets]"\ "\n\tList the domain groups of the specified user\n"); - d_printf("\nnet [method] user ADD <name> [-F user flags] [misc. options]"\ + d_printf("\nnet <method> user ADD <name> [password] [-F user flags] [misc. options]"\ " [targets]\n\tAdd specified user\n"); net_common_methods_usage(argc, argv); @@ -78,16 +79,66 @@ int net_help_user(int argc, const char **argv) return -1; } +int net_help_group(int argc, const char **argv) +{ + d_printf("net <method> group [misc. options] [targets]"\ + "\n\tList user groups\n\n"); + d_printf("net <method> group DELETE <name> [misc. options] [targets]"\ + "\n\tDelete specified group\n"); + d_printf("\nnet <method> group ADD <name> [-C comment]"\ + " [misc. options] [targets]\n\tCreate specified group\n"); + net_common_methods_usage(argc, argv); + net_common_flags_usage(argc, argv); + d_printf( + "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n"); + return -1; +} + +int net_help_share(int argc, const char **argv) +{ + d_printf( + "\nnet <method> share [misc. options] [targets] \n" + "\tenumerates all exported resources (network shares) " + "on target server\n" + "\nnet <method> share ADD <name=serverpath> [misc. options] [targets]" + "\n\tAdds a share from a server (makes the export active)\n" + "\nnet <method> share DELETE <sharename> [misc. options] [targets]\n" + "\n\tDeletes a share from a server (makes the export inactive)\n"); + net_common_methods_usage(argc, argv); + net_common_flags_usage(argc, argv); + d_printf( + "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n" + "\t-M or --maxusers=<num>\t\tmax users allowed for share\n"); + return -1; +} + +int net_help_file(int argc, const char **argv) +{ + d_printf("net <method> file [misc. options] [targets]\n"\ + "\tlists all open files on file server\n\n"); + d_printf("net <method> file USER <username> [misc. options] [targets]"\ + "\n\tlists all files opened by username on file server\n\n"); + d_printf("net <method> file CLOSE <id> [misc. options] [targets]\n"\ + "\tcloses specified file on target server\n\n"); + d_printf("net [rap] file INFO <id> [misc. options] [targets]\n"\ + "\tdisplays information about the specified open file\n"); + + net_common_methods_usage(argc, argv); + net_common_flags_usage(argc, argv); + return -1; +} + static int net_usage(int argc, const char **argv) { d_printf(" net time\t\tto view or set time information\n"\ " net lookup\t\tto lookup host name or ip address\n"\ " net user\t\tto manage users\n"\ + " net group\t\tto manage groups\n"\ " net join\t\tto join a domain\n"\ "\n"\ - " net ads [command]\tto run ADS commands\n"\ - " net rap [command]\tto run RAP (pre-RPC) commands\n"\ - " net rpc [command]\tto run RPC commands\n"\ + " net ads <command>\tto run ADS commands\n"\ + " net rap <command>\tto run RAP (pre-RPC) commands\n"\ + " net rpc <command>\tto run RPC commands\n"\ "\n"\ "Type \"net help <option>\" to get more information on that option\n"); return -1; @@ -103,14 +154,14 @@ int net_help(int argc, const char **argv) {"RAP", net_rap_help}, {"RPC", net_rpc_help}, - {"FILE", net_rap_file_usage}, - {"SHARE", net_rap_share_usage}, + {"FILE", net_help_file}, + {"SHARE", net_help_share}, {"SESSION", net_rap_session_usage}, {"SERVER", net_rap_server_usage}, {"DOMAIN", net_rap_domain_usage}, {"PRINTQ", net_rap_printq_usage}, {"USER", net_help_user}, - {"GROUP", net_rap_group_usage}, + {"GROUP", net_help_group}, {"VALIDATE", net_rap_validate_usage}, {"GROUPMEMBER", net_rap_groupmember_usage}, {"ADMIN", net_rap_admin_usage}, diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c index 0cc1ff579f..a324f594a1 100644 --- a/source3/utils/net_lookup.c +++ b/source3/utils/net_lookup.c @@ -23,8 +23,12 @@ int net_lookup_usage(int argc, const char **argv) { d_printf( -" net lookup host HOSTNAME <type>\n\tgives IP for a hostname\n\n"\ -"\n"); +" net lookup host HOSTNAME <type>\n\tgives IP for a hostname\n\n" +" net lookup ldap [domain]\n\tgives IP of domain's ldap server\n\n" +" net lookup kdc [realm]\n\tgives IP of realm's kerberos KDC\n\n" +" net lookup dc [domain]\n\tgives IP of domains Domain Controllers\n\n" +" net lookup master [domain|wg]\n\tgive IP of master browser\n\n" +); return -1; } @@ -48,12 +52,177 @@ static int net_lookup_host(int argc, const char **argv) return 0; } +static void print_ldap_srvlist(char *srvlist) +{ + char *cur, *next; + struct in_addr ip; + BOOL printit; + + cur = srvlist; + do { + next = strchr(cur,':'); + if (next) *next++='\0'; + printit = resolve_name(cur, &ip, 0x20); + cur=next; + next=cur ? strchr(cur,' ') :NULL; + if (next) + *next++='\0'; + if (printit) + d_printf("%s:%s\n", inet_ntoa(ip), cur?cur:""); + cur = next; + } while (next); +} + + +static int net_lookup_ldap(int argc, const char **argv) +{ +#ifdef HAVE_LDAP + char *srvlist, *domain; + int rc, count; + struct in_addr *addr; + struct hostent *hostent; + + if (argc > 0) + domain = argv[0]; + else + domain = opt_target_workgroup; + + DEBUG(9, ("Lookup up ldap for domain %s\n", domain)); + rc = ldap_domain2hostlist(domain, &srvlist); + if ((rc == LDAP_SUCCESS) && srvlist) { + print_ldap_srvlist(srvlist); + return 0; + } + + DEBUG(9, ("Looking up DC for domain %s\n", domain)); + if (!get_dc_list(True, domain, &addr, &count)) + return -1; + + hostent = gethostbyaddr((char *) &addr->s_addr, sizeof(addr->s_addr), + AF_INET); + if (!hostent) + return -1; + + DEBUG(9, ("Found DC with DNS name %s\n", hostent->h_name)); + domain = strchr(hostent->h_name, '.'); + if (!domain) + return -1; + domain++; + + DEBUG(9, ("Looking up ldap for domain %s\n", domain)); + rc = ldap_domain2hostlist(domain, &srvlist); + if ((rc == LDAP_SUCCESS) && srvlist) { + print_ldap_srvlist(srvlist); + return 0; + } + return -1; +#endif + DEBUG(1,("No LDAP support\n")); + return -1; +} + +static int net_lookup_dc(int argc, const char **argv) +{ + struct in_addr *ip_list; + char *pdc_str = NULL; + char *domain=opt_target_workgroup; + int count, i; + + if (argc > 0) + domain=argv[0]; + + /* first get PDC */ + if (!get_dc_list(True, domain, &ip_list, &count)) + return -1; + + asprintf(&pdc_str, "%s", inet_ntoa(*ip_list)); + d_printf("%s\n", pdc_str); + if (!get_dc_list(False, domain, &ip_list, &count)) { + SAFE_FREE(pdc_str); + return 0; + } + for (i=0;i<count;i++) { + char *dc_str = inet_ntoa(ip_list[i]); + if (!strequal(pdc_str, dc_str)) + d_printf("%s\n", dc_str); + } + SAFE_FREE(pdc_str); + return 0; +} + +static int net_lookup_master(int argc, const char **argv) +{ + struct in_addr master_ip; + char *domain=opt_target_workgroup; + + if (argc > 0) + domain=argv[0]; + + if (!find_master_ip(domain, &master_ip)) + return -1; + d_printf("%s\n", inet_ntoa(master_ip)); + return 0; +} + +static int net_lookup_kdc(int argc, const char **argv) +{ +#ifdef HAVE_KRB5 + krb5_error_code rc; + krb5_context ctx; + struct sockaddr_in *addrs; + int num_kdcs,i; + krb5_data realm; + char **realms; + + rc = krb5_init_context(&ctx); + if (rc) { + DEBUG(1,("krb5_init_context failed (%s)\n", + error_message(rc))); + return -1; + } + + if (argc>0) { + realm.data = (krb5_pointer) argv[0]; + realm.length = strlen(argv[0]); + } else if (lp_realm() && *lp_realm()) { + realm.data = (krb5_pointer) lp_realm(); + realm.length = strlen(realm.data); + } else { + rc = krb5_get_host_realm(ctx, NULL, &realms); + if (rc) { + DEBUG(1,("krb5_gethost_realm failed (%s)\n", + error_message(rc))); + return -1; + } + realm.data = (krb5_pointer) *realms; + realm.length = strlen(realm.data); + } + + rc = krb5_locate_kdc(ctx, &realm, &addrs, &num_kdcs, 0); + if (rc) { + DEBUG(1, ("krb5_locate_kdc failed (%s)\n", error_message(rc))); + return -1; + } + for (i=0;i<num_kdcs;i++) + if (addrs[i].sin_family == AF_INET) + d_printf("%s:%hd\n", inet_ntoa(addrs[i].sin_addr), + ntohs(addrs[i].sin_port)); + return 0; + +#endif + DEBUG(1, ("No kerberos support\n")); + return -1; +} /* lookup hosts or IP addresses using internal samba lookup fns */ int net_lookup(int argc, const char **argv) { struct functable func[] = { {"HOST", net_lookup_host}, + {"LDAP", net_lookup_ldap}, + {"DC", net_lookup_dc}, + {"MASTER", net_lookup_master}, + {"KDC", net_lookup_kdc}, {NULL, NULL} }; diff --git a/source3/utils/net_rap.c b/source3/utils/net_rap.c index a6b199fd88..af0a6adbd2 100644 --- a/source3/utils/net_rap.c +++ b/source3/utils/net_rap.c @@ -35,7 +35,7 @@ #define ERRMSG_BOTH_SERVER_IPADDRESS "\nTarget server and IP address both "\ "specified. Do not set both at the same time. The target IP address was used\n" -static const char *share_type[] = { +const char *share_type[] = { "Disk", "Print", "Dev", @@ -50,15 +50,7 @@ static int errmsg_not_implemented(void) int net_rap_file_usage(int argc, const char **argv) { - d_printf("net rap file [misc. options] [targets]\n"\ - "\tlists all open files on file server\n\n"); - d_printf("net rap file USER <username> [misc. options] [targets]\n"\ - "\tlists all files opened by username on file server\n\n"); - d_printf("net rap file CLOSE <id> [misc. options] [targets]\n"\ - "\tcloses specified file on target server\n"); - - net_common_flags_usage(argc, argv); - return -1; + return net_help_file(argc, argv); } /*************************************************************************** @@ -67,7 +59,7 @@ int net_rap_file_usage(int argc, const char **argv) static void file_fn(const char * pPath, const char * pUser, uint16 perms, uint16 locks, uint32 id) { - d_printf("\t%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n", + d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n", id, pUser, perms, locks, pPath); } @@ -143,8 +135,8 @@ int net_rap_file(int argc, const char **argv) /* list open files */ d_printf( "\nEnumerating open files on remote server:\n\n"\ - "\n\tFileId Opened by Perms Locks Path \n"\ - "\t------ --------- ----- ----- ---- \n"); + "\nFileId Opened by Perms Locks Path \n"\ + "------ --------- ----- ----- ---- \n"); ret = cli_NetFileEnum(cli, NULL, NULL, file_fn); cli_shutdown(cli); return ret; @@ -155,23 +147,7 @@ int net_rap_file(int argc, const char **argv) int net_rap_share_usage(int argc, const char **argv) { - d_printf( - "\nnet [rap] share [misc. options] [targets] \n"\ - "\tenumerates all exported resources (network shares) "\ - "on target server\n"); - d_printf( - "\nnet rap share ADD <name=serverpath> [misc. options] [targets]"\ - "\n\tAdds a share from a server (makes the export active)\n"); - d_printf( - "\nnet rap share DELETE <sharename> [misc. options] [targets]\n"\ - "\tor"\ - "\nnet rap share CLOSE <sharename> [misc. options] [targets]"\ - "\n\tDeletes a share from a server (makes the export inactive)\n"); - net_common_flags_usage(argc, argv); - d_printf( - "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n"); - d_printf("\t-M or --maxusers=<num>\t\tmax users allowed for share\n"); - return -1; + return net_help_share(argc, argv); } static void long_share_fn(const char *share_name, uint32 type, @@ -518,7 +494,7 @@ static void enum_queue(const char *queuename, uint16 pri, uint16 start, static void enum_jobs(uint16 jobid, const char *ownername, const char *notifyname, const char *datatype, const char *jparms, uint16 pos, uint16 status, - const char *jstatus, uint submitted, uint jobsize, + const char *jstatus, unsigned int submitted, unsigned int jobsize, const char *comment) { d_printf(" %-23.23s %5d %9d ", @@ -672,8 +648,9 @@ static int rap_user_add(int argc, const char **argv) userinfo.priv = 1; userinfo.home_dir = NULL; userinfo.logon_script = NULL; - + ret = cli_NetUserAdd(cli, &userinfo); + cli_shutdown(cli); return ret; } @@ -732,17 +709,7 @@ int net_rap_user(int argc, const char **argv) int net_rap_group_usage(int argc, const char **argv) { - d_printf("net rap group [misc. options] [targets]"\ - "\n\tList user groups\n"); - d_printf("\nnet rap group DELETE <name> [misc. options] [targets]"\ - "\n\tDelete specified group\n"); - d_printf("\nnet rap group ADD <name> [-C comment] [misc. options]"\ - " [targets]\n\tCreate specified group\n"); - - net_common_flags_usage(argc, argv); - d_printf( - "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n"); - return -1; + return net_help_group(argc, argv); } static void long_group_fn(const char *group_name, const char *comment, diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 19e2c63ecc..dc50c438d4 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -2,6 +2,7 @@ Samba Unix/Linux SMB client library Distributed SMB/CIFS Server Management Utility Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org) + Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -59,13 +60,13 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli) TALLOC_CTX *mem_ctx; if (!(domain_sid = malloc(sizeof(DOM_SID)))){ - DEBUG(0,("fetch_domain_sid: malloc returned NULL!\n")); + DEBUG(0,("net_get_remote_domain_sid: malloc returned NULL!\n")); goto error; } if (!(mem_ctx=talloc_init())) { - DEBUG(0,("fetch_domain_sid: talloc_init returned NULL!\n")); + DEBUG(0,("net_get_remote_domain_sid: talloc_init returned NULL!\n")); goto error; } @@ -146,7 +147,7 @@ static int run_rpc_command(const char *pipe_name, int conn_flags, nt_status = fn(domain_sid, cli, mem_ctx, argc, argv); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0, ("rpc command function failed! (%s)\n", nt_errstr(nt_status))); + DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status))); } else { DEBUG(5, ("rpc command function succedded\n")); } @@ -235,6 +236,14 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl fstrcpy(trust_passwd, global_myname); strlower(trust_passwd); + + /* + * Machine names can be 15 characters, but the max length on + * a password is 14. --jerry + */ + + trust_passwd[14] = '\0'; + E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash); return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash); @@ -296,6 +305,80 @@ int net_rpc_join(int argc, const char **argv) } + +/** + * display info about a rpc domain + * + * All paramaters are provided by the run_rpc_command function, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ + +static NTSTATUS +rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + POLICY_HND connect_pol, domain_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + SAM_UNK_CTR ctr; + + /* Get sam policy handle */ + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Get domain policy handle */ + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + domain_sid, &domain_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + ZERO_STRUCT(ctr); + result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol, + 2, &ctr); + if (NT_STATUS_IS_OK(result)) { + TALLOC_CTX *ctx = talloc_init(); + d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain)); + d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num); + d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs); + d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps); + d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps); + talloc_destroy(ctx); + } + + done: + return result; +} + + +/** + * 'net rpc info' entrypoint. + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + **/ +int net_rpc_info(int argc, const char **argv) +{ + return run_rpc_command(PIPE_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, + rpc_info_internals, + argc, argv); +} + + + + /****************************************************************************/ /** @@ -451,7 +534,7 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid, uint32 flags = 0x000003e8; /* Unknown */ result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, - flags, 1, (char **) &argv[0], + flags, 1, &argv[0], &num_rids, &user_rids, &name_types); @@ -548,7 +631,7 @@ rpc_user_info_internals(const DOM_SID *domain_sid, struct cli_state *cli, /* Get handle on user */ result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, - flags, 1, (char **) &argv[0], + flags, 1, &argv[0], &num_rids, &rids, &name_types); if (!NT_STATUS_IS_OK(result)) goto done; @@ -604,7 +687,7 @@ static int rpc_user_info(int argc, const char **argv) /** * List users on a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All paramaters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -664,7 +747,7 @@ rpc_user_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, if (opt_long_list_entries) printf("%-21.21s %-50.50s\n", user, desc); else - printf("%-21.21s\n", user); + printf("%s\n", user); } } while (!NT_STATUS_IS_OK(result)); @@ -703,19 +786,532 @@ int net_rpc_user(int argc, const char **argv) /****************************************************************************/ +/** + * Basic usage function for 'net rpc group' + * @param argc Standard main() style argc. + * @param argv Standard main() style argv. Initial components are already + * stripped. + **/ +static int rpc_group_usage(int argc, const char **argv) +{ + return net_help_group(argc, argv); +} /** - * ABORT the shutdown of a remote RPC Server + * List groups on a remote RPC server + * + * All paramaters are provided by the run_rpc_command funcion, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ + +static NTSTATUS +rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + POLICY_HND connect_pol, domain_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + uint32 start_idx=0, max_entries=250, num_entries, i; + struct acct_info *groups; + DOM_SID global_sid_Builtin; + + string_to_sid(&global_sid_Builtin, "S-1-5-32"); + + /* Get sam policy handle */ + + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Get domain policy handle */ + + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + domain_sid, &domain_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + /* Query domain groups */ + if (opt_long_list_entries) + d_printf("\nGroup name Comment"\ + "\n-----------------------------\n"); + do { + result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol, + &start_idx, max_entries, + &groups, &num_entries); + + for (i = 0; i < num_entries; i++) { + if (opt_long_list_entries) + printf("%-21.21s %-50.50s\n", + groups[i].acct_name, + groups[i].acct_desc); + else + printf("%-21.21s\n", groups[i].acct_name); + } + } while (!NT_STATUS_IS_OK(result)); + /* query domain aliases */ + do { + result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol, + &start_idx, max_entries, + &groups, &num_entries); + + for (i = 0; i < num_entries; i++) { + if (opt_long_list_entries) + printf("%-21.21s %-50.50s\n", + groups[i].acct_name, + groups[i].acct_desc); + else + printf("%-21.21s\n", groups[i].acct_name); + } + } while (!NT_STATUS_IS_OK(result)); + cli_samr_close(cli, mem_ctx, &domain_pol); + /* Get builtin policy handle */ + + result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &global_sid_Builtin, &domain_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + /* query builtin aliases */ + do { + result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol, + &start_idx, max_entries, + &groups, &num_entries); + + for (i = 0; i < num_entries; i++) { + if (opt_long_list_entries) + printf("%-21.21s %-50.50s\n", + groups[i].acct_name, + groups[i].acct_desc); + else + printf("%s\n", groups[i].acct_name); + } + } while (!NT_STATUS_IS_OK(result)); + + done: + return result; +} + +/** + * 'net rpc group' entrypoint. + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + **/ + +int net_rpc_group(int argc, const char **argv) +{ + struct functable func[] = { +#if 0 + {"add", rpc_group_add}, + {"delete", rpc_group_delete}, +#endif + {NULL, NULL} + }; + + if (argc == 0) { + if (opt_long_list_entries) { + } else { + } + return run_rpc_command(PIPE_SAMR, 0, + rpc_group_list_internals, + argc, argv); + } + + return net_run_function(argc, argv, func, rpc_group_usage); +} + +/****************************************************************************/ + +static int rpc_share_usage(int argc, const char **argv) +{ + return net_help_share(argc, argv); +} + +/** + * Add a share on a remote RPC server + * + * All paramaters are provided by the run_rpc_command function, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ +static NTSTATUS +rpc_share_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx,int argc, const char **argv) +{ + WERROR result; + char *sharename=talloc_strdup(mem_ctx, argv[0]); + char *path; + uint32 type=0; /* only allow disk shares to be added */ + uint32 num_users=0, perms=0; + char *password=NULL; /* don't allow a share password */ + + path = strchr(sharename, '='); + if (!path) + return NT_STATUS_UNSUCCESSFUL; + *path++ = '\0'; + + result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type, + opt_comment, perms, opt_maxusers, + num_users, path, password); + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +static int rpc_share_add(int argc, const char **argv) +{ + if ((argc < 1) || !strchr(argv[0], '=')) { + DEBUG(1,("Sharename or path not specified on add\n")); + return rpc_share_usage(argc, argv); + } + return run_rpc_command(PIPE_SRVSVC, 0, + rpc_share_add_internals, + argc, argv); +} + +/** + * Delete a share on a remote RPC server + * + * All paramaters are provided by the run_rpc_command function, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ +static NTSTATUS +rpc_share_del_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx,int argc, const char **argv) +{ + WERROR result; + + result = cli_srvsvc_net_share_del(cli, mem_ctx, argv[0]); + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +/** + * Delete a share on a remote RPC server + * + * @param domain_sid The domain sid acquired from the remote server + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ +static int rpc_share_delete(int argc, const char **argv) +{ + if (argc < 1) { + DEBUG(1,("Sharename not specified on delete\n")); + return rpc_share_usage(argc, argv); + } + return run_rpc_command(PIPE_SRVSVC, 0, + rpc_share_del_internals, + argc, argv); +} + +/** + * Formatted print of share info + * + * @param info1 pointer to SRV_SHARE_INFO_1 to format + **/ + +static void display_share_info_1(SRV_SHARE_INFO_1 *info1) +{ + fstring netname = "", remark = ""; + + rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname); + rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark); + + if (opt_long_list_entries) { + d_printf("%-12.12s %-8.8s %-50.50s\n", + netname, share_type[info1->info_1.type], remark); + } else { + d_printf("%-12.12s\n", netname); + } + +} + +/** + * List shares on a remote RPC server + * + * All paramaters are provided by the run_rpc_command function, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ + +static NTSTATUS +rpc_share_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + SRV_SHARE_INFO_CTR ctr; + WERROR result; + ENUM_HND hnd; + uint32 preferred_len = 0xffffffff, i; + + init_enum_hnd(&hnd, 0); + + result = cli_srvsvc_net_share_enum( + cli, mem_ctx, 1, &ctr, preferred_len, &hnd); + + if (!W_ERROR_IS_OK(result)) + goto done; + + /* Display results */ + + if (opt_long_list_entries) { + d_printf( + "\nEnumerating shared resources (exports) on remote server:\n\n"\ + "\nShare name Type Description\n"\ + "---------- ---- -----------\n"); + } + for (i = 0; i < ctr.num_entries; i++) + display_share_info_1(&ctr.share.info1[i]); + done: + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +/** + * 'net rpc share' entrypoint. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + **/ + +int net_rpc_share(int argc, const char **argv) +{ + struct functable func[] = { + {"add", rpc_share_add}, + {"delete", rpc_share_delete}, + {NULL, NULL} + }; + + if (argc == 0) + return run_rpc_command(PIPE_SRVSVC, 0, + rpc_share_list_internals, + argc, argv); + + return net_run_function(argc, argv, func, rpc_share_usage); +} + +/****************************************************************************/ + +static int rpc_file_usage(int argc, const char **argv) +{ + return net_help_file(argc, argv); +} + +/** + * Close a file on a remote RPC server + * + * All paramaters are provided by the run_rpc_command function, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ +static NTSTATUS +rpc_file_close_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + WERROR result; + result = cli_srvsvc_net_file_close(cli, mem_ctx, atoi(argv[0])); + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +/** + * Close a file on a remote RPC server + * + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ +static int rpc_file_close(int argc, const char **argv) +{ + if (argc < 1) { + DEBUG(1, ("No fileid given on close\n")); + return(rpc_file_usage(argc, argv)); + } + + return run_rpc_command(PIPE_SRVSVC, 0, + rpc_file_close_internals, + argc, argv); +} + +/** + * Formatted print of open file info + * + * @param info3 FILE_INFO_3 contents + * @param str3 strings for FILE_INFO_3 + **/ + +static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3) +{ + fstring user = "", path = ""; + + rpcstr_pull_unistr2_fstring(user, &str3->uni_user_name); + rpcstr_pull_unistr2_fstring(path, &str3->uni_path_name); + + d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n", + info3->id, user, info3->perms, info3->num_locks, path); +} + +/** + * List open files on a remote RPC server * * All paramaters are provided by the run_rpc_command funcion, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ + +static NTSTATUS +rpc_file_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + SRV_FILE_INFO_CTR ctr; + WERROR result; + ENUM_HND hnd; + uint32 preferred_len = 0xffffffff, i; + char *username=NULL; + + init_enum_hnd(&hnd, 0); + + /* if argc > 0, must be user command */ + if (argc > 0) + username = argv[0]; + + result = cli_srvsvc_net_file_enum( + cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd); + + if (!W_ERROR_IS_OK(result)) + goto done; + + /* Display results */ + + d_printf( + "\nEnumerating open files on remote server:\n\n"\ + "\nFileId Opened by Perms Locks Path"\ + "\n------ --------- ----- ----- ---- \n"); + for (i = 0; i < ctr.num_entries; i++) + display_file_info_3(&ctr.file.info3[i].info_3, + &ctr.file.info3[i].info_3_str); + done: + return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + + +/** + * List files for a user on a remote RPC server + * + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return A shell status integer (0 for success) + **/ +static int rpc_file_user(int argc, const char **argv) +{ + if (argc < 1) { + DEBUG(1, ("No username given\n")); + return(rpc_file_usage(argc, argv)); + } + + return run_rpc_command(PIPE_SRVSVC, 0, + rpc_file_list_internals, + argc, argv); +} + + +/** + * 'net rpc file' entrypoint. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + **/ + +int net_rpc_file(int argc, const char **argv) +{ + struct functable func[] = { + {"close", rpc_file_close}, + {"user", rpc_file_user}, +#if 0 + {"info", rpc_file_info}, +#endif + {NULL, NULL} + }; + + if (argc == 0) + return run_rpc_command(PIPE_SRVSVC, 0, + rpc_file_list_internals, + argc, argv); + + return net_run_function(argc, argv, func, rpc_file_usage); +} + +/****************************************************************************/ + + + +/** + * ABORT the shutdown of a remote RPC Server + * + * All paramaters are provided by the run_rpc_command function, except for * argc, argv which are passed through. * * @param domain_sid The domain sid aquired from the remote server * @param cli A cli_state connected to the server. * @param mem_ctx Talloc context, destoyed on compleation of the function. * @param argc Standard main() style argc - * @param argc Standard main() style argv. Initial components are already + * @param argv Standard main() style argv. Initial components are already * stripped * * @return Normal NTSTATUS return. @@ -741,7 +1337,7 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct c * ABORT the Shut down of a remote RPC server * * @param argc Standard main() style argc - * @param argc Standard main() style argv. Initial components are already + * @param argv Standard main() style argv. Initial components are already * stripped * * @return A shell status integer (0 for success) @@ -874,7 +1470,7 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli if (argc != 1) { d_printf("Usage: net rpc trustdom add <domain_name>\n"); - return NT_STATUS_OK; + return NT_STATUS_INVALID_PARAMETER; } /* @@ -985,6 +1581,12 @@ static int rpc_trustdom_establish(int argc, const char **argv) { * Connect to \\server\ipc$ as 'our domain' account with password */ + if (argc != 1) { + d_printf("Usage: net rpc trustdom add <domain_name>\n"); + return -1; + } + + domain_name = smb_xstrdup(argv[0]); strupper(domain_name); @@ -1061,10 +1663,8 @@ static int rpc_trustdom_establish(int argc, const char **argv) { return -1; } - if (cli->nt_pipe_fnum) { + if (cli->nt_pipe_fnum) cli_nt_session_close(cli); - talloc_destroy(mem_ctx); - } /* @@ -1104,6 +1704,17 @@ static int rpc_trustdom_establish(int argc, const char **argv) { but I still don't know if it's _really_ necessary */ /* + * Store the password in secrets db + */ + + if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer, + wks_info.uni_lan_grp.uni_str_len, opt_password, + domain_sid)) { + DEBUG(0, ("Storing password for trusted domain failed.\n")); + return -1; + } + + /* * Close the pipes and clean up */ @@ -1116,20 +1727,9 @@ static int rpc_trustdom_establish(int argc, const char **argv) { if (cli->nt_pipe_fnum) cli_nt_session_close(cli); - - talloc_destroy(mem_ctx); + talloc_destroy(mem_ctx); - /* - * Store the password in secrets db - */ - - if (!secrets_store_trusted_domain_password(domain_name, opt_password, - domain_sid)) { - DEBUG(0, ("Storing password for trusted domain failed.\n")); - return -1; - } - DEBUG(0, ("Success!\n")); return 0; } @@ -1260,12 +1860,17 @@ BOOL net_rpc_check(unsigned flags) int net_rpc_usage(int argc, const char **argv) { + d_printf(" net rpc info \t\t\tshow basic info about a domain \n"); d_printf(" net rpc join \t\t\tto join a domain \n"); d_printf(" net rpc user \t\t\tto add, delete and list users\n"); + d_printf(" net rpc group \t\tto list groups\n"); + d_printf(" net rpc share \t\tto add, delete, and list shares\n"); + d_printf(" net rpc file \t\t\tto list open files\n"); d_printf(" net rpc changetrustpw \tto change the trust account password\n"); - d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n"); - d_printf(" net rpc abortshutdown \tto to abort the shutdown of a remote server\n"); - d_printf(" net rpc shutdown \t\tto to shutdown a remote server\n"); + d_printf(" net rpc trustdom \t\tto create trusting domain's account\n" + "\t\t\t\t\tor establish trust\n"); + d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n"); + d_printf(" net rpc shutdown \t\tto shutdown a remote server\n"); d_printf("\n"); d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */ d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n"); @@ -1288,7 +1893,9 @@ int net_rpc_help(int argc, const char **argv) { struct functable func[] = { {"join", rpc_join_usage}, - {"user", net_help_user}, + {"user", rpc_user_usage}, + {"group", rpc_group_usage}, + {"share", rpc_share_usage}, /*{"changetrustpw", rpc_changetrustpw_usage}, */ {"trustdom", rpc_trustdom_usage}, /*{"abortshutdown", rpc_shutdown_abort_usage},*/ @@ -1315,8 +1922,12 @@ int net_rpc_help(int argc, const char **argv) int net_rpc(int argc, const char **argv) { struct functable func[] = { + {"info", net_rpc_info}, {"join", net_rpc_join}, {"user", net_rpc_user}, + {"group", net_rpc_group}, + {"share", net_rpc_share}, + {"file", net_rpc_file}, {"changetrustpw", rpc_changetrustpw}, {"trustdom", rpc_trustdom}, {"abortshutdown", rpc_shutdown_abort}, diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index c4558ea10b..cc1a203ca1 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -53,7 +53,6 @@ int net_rpc_join_newstyle(int argc, const char **argv) /* libsmb variables */ struct cli_state *cli; - fstring acct_name; TALLOC_CTX *mem_ctx; uint32 acb_info; @@ -81,7 +80,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) fstring domain; uint32 num_rids, *name_types, *user_rids; uint32 flags = 0x3e8; - char *names; + const char *acct_name; /* Connect to remote machine */ @@ -132,8 +131,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) "could not open domain"); /* Create domain user */ - fstrcpy(acct_name, global_myname); - fstrcat(acct_name, "$"); + acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname); strlower(acct_name); acb_info = ((lp_server_role() == ROLE_DOMAIN_BDC) || lp_server_role() == ROLE_DOMAIN_PDC) ? ACB_SVRTRUST : ACB_WSTRUST; @@ -162,11 +160,9 @@ int net_rpc_join_newstyle(int argc, const char **argv) if (NT_STATUS_IS_OK(result)) cli_samr_close(cli, mem_ctx, &user_pol); - names = (char *)&acct_name[0]; - CHECK_RPC_ERR_DEBUG(cli_samr_lookup_names(cli, mem_ctx, &domain_pol, flags, - 1, &names, &num_rids, + 1, &acct_name, &num_rids, &user_rids, &name_types), ("error looking up rid for user %s: %s\n", acct_name, nt_errstr(result))); diff --git a/source3/utils/net_time.c b/source3/utils/net_time.c index 3f5532109c..13c75c80b0 100644 --- a/source3/utils/net_time.c +++ b/source3/utils/net_time.c @@ -166,8 +166,10 @@ int net_time(int argc, const char **argv) {NULL, NULL} }; - if (!opt_host && !opt_have_ip) { - d_printf("You must specify a hostname or IP\n"); + if (!opt_host && !opt_have_ip && + !find_master_ip(opt_target_workgroup, &opt_dest_ip)) { + d_printf("Could not locate a time server. Try "\ + "specifying a target host.\n"); net_time_usage(argc,argv); return -1; } diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c index 9549d16d04..8e4f5aab03 100644 --- a/source3/utils/nmblookup.c +++ b/source3/utils/nmblookup.c @@ -25,6 +25,7 @@ extern BOOL AllowDebugChange; +static BOOL give_flags = False; static BOOL use_bcast = True; static BOOL got_bcast = False; static struct in_addr bcast_addr; @@ -63,6 +64,7 @@ static void usage(void) d_printf("Version %s\n",VERSION); d_printf("\t-d debuglevel set the debuglevel\n"); d_printf("\t-B broadcast address the address to use for broadcasts\n"); + d_printf("\t-f list the NMB flags returned\n"); d_printf("\t-U unicast address the address to use for unicast\n"); d_printf("\t-M searches for a master browser\n"); d_printf("\t-R set recursion desired in packet\n"); @@ -99,6 +101,24 @@ static char *node_status_flags(unsigned char flags) } /**************************************************************************** +turn the NMB Query flags into a string +****************************************************************************/ +static char *query_flags(int flags) +{ + static fstring ret1; + fstrcpy(ret1, ""); + + if (flags & NM_FLAGS_RS) fstrcat(ret1, "Response "); + if (flags & NM_FLAGS_AA) fstrcat(ret1, "Authoritative "); + if (flags & NM_FLAGS_TC) fstrcat(ret1, "Truncated "); + if (flags & NM_FLAGS_RD) fstrcat(ret1, "Recursion_Desired "); + if (flags & NM_FLAGS_RA) fstrcat(ret1, "Recursion_Available "); + if (flags & NM_FLAGS_B) fstrcat(ret1, "Broadcast "); + + return ret1; +} + +/**************************************************************************** do a node status query ****************************************************************************/ static void do_node_status(int fd, char *name, int type, struct in_addr ip) @@ -132,14 +152,14 @@ send out one query ****************************************************************************/ static BOOL query_one(char *lookup, unsigned int lookup_type) { - int j, count; + int j, count, flags = 0; struct in_addr *ip_list=NULL; if (got_bcast) { d_printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr)); ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast, use_bcast?True:recursion_desired, - bcast_addr,&count); + bcast_addr,&count, &flags, NULL); } else { struct in_addr *bcast; for (j=iface_count() - 1; @@ -151,12 +171,15 @@ static BOOL query_one(char *lookup, unsigned int lookup_type) ip_list = name_query(ServerFD,lookup,lookup_type, use_bcast, use_bcast?True:recursion_desired, - *bcast,&count); + *bcast,&count, &flags, NULL); } } if (!ip_list) return False; + if (give_flags) + d_printf("Flags: %s\n", query_flags(flags)); + for (j=0;j<count;j++) { if (translate_addresses) { struct hostent *host = gethostbyaddr((char *)&ip_list[j], sizeof(ip_list[j]), AF_INET); @@ -203,7 +226,7 @@ int main(int argc,char *argv[]) setup_logging(argv[0],True); - while ((opt = getopt(argc, argv, "d:B:U:i:s:SMrhART")) != EOF) + while ((opt = getopt(argc, argv, "d:fB:U:i:s:SMrhART")) != EOF) switch (opt) { case 'B': @@ -211,6 +234,9 @@ int main(int argc,char *argv[]) got_bcast = True; use_bcast = True; break; + case 'f': + give_flags = True; + break; case 'U': bcast_addr = *interpret_addr2(optarg); got_bcast = True; diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 1fb1f2355b..b30ab6f38e 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -4,6 +4,7 @@ Copyright (C) Simo Sorce 2000 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 @@ -25,40 +26,40 @@ extern pstring global_myname; extern BOOL AllowDebugChange; -/* - * Next two lines needed for SunOS and don't - * hurt anything else... - */ -extern char *optarg; -extern int optind; - /********************************************************* - Print command usage on stderr and die. -**********************************************************/ -static void usage(void) -{ - if (getuid() == 0) { - printf("pdbedit options\n"); - } else { - printf("You need to be root to use this tool!\n"); + Add all currently available users to another db + ********************************************************/ + +int export_database (struct pdb_context *in, char *db){ + struct pdb_context *context; + SAM_ACCOUNT *user = NULL; + + if (!NT_STATUS_IS_OK(make_pdb_context_string(&context, db))){ + fprintf(stderr, "Can't initialize %s.\n", db); + return 1; + } + + if (!in->pdb_setsampwent(in, 0)){ + fprintf(stderr, "Can't sampwent!\n"); + return 1; + } + + if (!NT_STATUS_IS_OK(pdb_init_sam(&user))){ + fprintf(stderr, "Can't initialize new SAM_ACCOUNT!\n"); + return 1; + } + + while (in->pdb_getsampwent(in,user)){ + context->pdb_add_sam_account(context,user); + if (!NT_STATUS_IS_OK(pdb_reset_sam(user))){ + fprintf(stderr, "Can't reset SAM_ACCOUNT!\n"); + return 1; + } } - printf("(actually to add a user you need to use smbpasswd)\n"); - printf("options:\n"); - printf(" -l list usernames\n"); - printf(" -v verbose output\n"); - printf(" -w smbpasswd file style\n"); - printf(" -u username print user's info\n"); - printf(" -f fullname set Full Name\n"); - printf(" -h homedir set home directory\n"); - printf(" -d drive set home dir drive\n"); - printf(" -s script set logon script\n"); - printf(" -p profile set profile path\n"); - printf(" -a create new account\n"); - printf(" -m it is a machine trust\n"); - printf(" -x delete this user\n"); - printf(" -i file import account from file (smbpasswd style)\n"); - printf(" -D debuglevel set DEBUGELEVEL (default = 1)\n"); - exit(1); + + in->pdb_endsampwent(in); + + return 0; } /********************************************************* @@ -69,24 +70,53 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst { uid_t uid; gid_t gid; + time_t tmp; /* TODO: chaeck if entry is a user or a workstation */ if (!sam_pwent) return -1; if (verbosity) { - printf ("username: %s\n", pdb_get_username(sam_pwent)); + printf ("Unix username: %s\n", pdb_get_username(sam_pwent)); + printf ("NT username: %s\n", pdb_get_nt_username(sam_pwent)); + printf ("Account Flags: %s\n", pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent), NEW_PW_FORMAT_SPACE_PADDED_LEN)); + if (IS_SAM_UNIX_USER(sam_pwent)) { uid = pdb_get_uid(sam_pwent); gid = pdb_get_gid(sam_pwent); - printf ("user ID/Group: %d/%d\n", uid, gid); + printf ("User ID/Group ID: %d/%d\n", uid, gid); } - printf ("user RID/GRID: %u/%u\n", (unsigned int)pdb_get_user_rid(sam_pwent), - (unsigned int)pdb_get_group_rid(sam_pwent)); - printf ("Full Name: %s\n", pdb_get_fullname(sam_pwent)); - printf ("Home Directory: %s\n", pdb_get_homedir(sam_pwent)); - printf ("HomeDir Drive: %s\n", pdb_get_dirdrive(sam_pwent)); - printf ("Logon Script: %s\n", pdb_get_logon_script(sam_pwent)); - printf ("Profile Path: %s\n", pdb_get_profile_path(sam_pwent)); + printf ("User SID: %s\n", + sid_string_static(pdb_get_user_sid(sam_pwent))); + printf ("Primary Group SID: %s\n", + sid_string_static(pdb_get_group_sid(sam_pwent))); + printf ("Full Name: %s\n", pdb_get_fullname(sam_pwent)); + printf ("Home Directory: %s\n", pdb_get_homedir(sam_pwent)); + printf ("HomeDir Drive: %s\n", pdb_get_dirdrive(sam_pwent)); + printf ("Logon Script: %s\n", pdb_get_logon_script(sam_pwent)); + printf ("Profile Path: %s\n", pdb_get_profile_path(sam_pwent)); + printf ("Domain: %s\n", pdb_get_domain(sam_pwent)); + printf ("Account desc: %s\n", pdb_get_acct_desc(sam_pwent)); + printf ("Workstations: %s\n", pdb_get_workstations(sam_pwent)); + printf ("Munged dial: %s\n", pdb_get_munged_dial(sam_pwent)); + + tmp = pdb_get_logon_time(sam_pwent); + printf ("Logon time: %s\n", tmp ? http_timestring(tmp) : "0"); + + tmp = pdb_get_logoff_time(sam_pwent); + printf ("Logoff time: %s\n", tmp ? http_timestring(tmp) : "0"); + + tmp = pdb_get_kickoff_time(sam_pwent); + printf ("Kickoff time: %s\n", tmp ? http_timestring(tmp) : "0"); + + tmp = pdb_get_pass_last_set_time(sam_pwent); + printf ("Password last set: %s\n", tmp ? http_timestring(tmp) : "0"); + + tmp = pdb_get_pass_can_change_time(sam_pwent); + printf ("Password can change: %s\n", tmp ? http_timestring(tmp) : "0"); + + tmp = pdb_get_pass_must_change_time(sam_pwent); + printf ("Password must change: %s\n", tmp ? http_timestring(tmp) : "0"); + } else if (smbpwdstyle) { if (IS_SAM_UNIX_USER(sam_pwent)) { char lm_passwd[33]; @@ -126,7 +156,7 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst Get an Print User Info **********************************************************/ -static int print_user_info (char *username, BOOL verbosity, BOOL smbpwdstyle) +static int print_user_info (struct pdb_context *in, char *username, BOOL verbosity, BOOL smbpwdstyle) { SAM_ACCOUNT *sam_pwent=NULL; BOOL ret; @@ -135,7 +165,7 @@ static int print_user_info (char *username, BOOL verbosity, BOOL smbpwdstyle) return -1; } - ret = pdb_getsampwnam (sam_pwent, username); + ret = in->pdb_getsampwnam (in, sam_pwent, username); if (ret==False) { fprintf (stderr, "Username not found!\n"); @@ -152,22 +182,20 @@ static int print_user_info (char *username, BOOL verbosity, BOOL smbpwdstyle) /********************************************************* List Users **********************************************************/ -static int print_users_list (BOOL verbosity, BOOL smbpwdstyle) +static int print_users_list (struct pdb_context *in, BOOL verbosity, BOOL smbpwdstyle) { SAM_ACCOUNT *sam_pwent=NULL; BOOL check, ret; - errno = 0; /* testing --simo */ - check = pdb_setsampwent(False); - if (check && errno == ENOENT) { - fprintf (stderr,"Password database not found!\n"); - exit(1); + check = in->pdb_setsampwent(in, False); + if (!check) { + return 1; } check = True; if (!(NT_STATUS_IS_OK(pdb_init_sam(&sam_pwent)))) return 1; - while (check && (ret = pdb_getsampwent (sam_pwent))) { + while (check && (ret = in->pdb_getsampwent (in, sam_pwent))) { if (verbosity) printf ("---------------\n"); print_sam_info (sam_pwent, verbosity, smbpwdstyle); @@ -176,7 +204,7 @@ static int print_users_list (BOOL verbosity, BOOL smbpwdstyle) } if (check) pdb_free_sam(&sam_pwent); - pdb_endsampwent(); + in->pdb_endsampwent(in); return 0; } @@ -184,14 +212,14 @@ static int print_users_list (BOOL verbosity, BOOL smbpwdstyle) Set User Info **********************************************************/ -static int set_user_info (char *username, char *fullname, char *homedir, char *drive, char *script, char *profile) +static int set_user_info (struct pdb_context *in, char *username, char *fullname, char *homedir, char *drive, char *script, char *profile) { SAM_ACCOUNT *sam_pwent=NULL; BOOL ret; pdb_init_sam(&sam_pwent); - ret = pdb_getsampwnam (sam_pwent, username); + ret = in->pdb_getsampwnam (in, sam_pwent, username); if (ret==False) { fprintf (stderr, "Username not found!\n"); pdb_free_sam(&sam_pwent); @@ -209,8 +237,8 @@ static int set_user_info (char *username, char *fullname, char *homedir, char *d if (profile) pdb_set_profile_path (sam_pwent, profile, True); - if (pdb_update_sam_account (sam_pwent)) - print_user_info (username, True, False); + if (in->pdb_update_sam_account (in, sam_pwent)) + print_user_info (in, username, True, False); else { fprintf (stderr, "Unable to modify entry!\n"); pdb_free_sam(&sam_pwent); @@ -223,7 +251,7 @@ static int set_user_info (char *username, char *fullname, char *homedir, char *d /********************************************************* Add New User **********************************************************/ -static int new_user (char *username, char *fullname, char *homedir, char *drive, char *script, char *profile) +static int new_user (struct pdb_context *in, char *username, char *fullname, char *homedir, char *drive, char *script, char *profile) { SAM_ACCOUNT *sam_pwent=NULL; struct passwd *pwd = NULL; @@ -265,8 +293,8 @@ static int new_user (char *username, char *fullname, char *homedir, char *drive, pdb_set_acct_ctrl (sam_pwent, ACB_NORMAL); - if (pdb_add_sam_account (sam_pwent)) { - print_user_info (username, True, False); + if (in->pdb_add_sam_account (in, sam_pwent)) { + print_user_info (in, username, True, False); } else { fprintf (stderr, "Unable to add user! (does it alredy exist?)\n"); pdb_free_sam (&sam_pwent); @@ -280,7 +308,7 @@ static int new_user (char *username, char *fullname, char *homedir, char *drive, Add New Machine **********************************************************/ -static int new_machine (char *machinename) +static int new_machine (struct pdb_context *in, char *machinename) { SAM_ACCOUNT *sam_pwent=NULL; char name[16]; @@ -305,10 +333,10 @@ static int new_machine (char *machinename) pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST); - pdb_set_group_rid(sam_pwent, DOMAIN_GROUP_RID_COMPUTERS); + pdb_set_group_sid_from_rid(sam_pwent, DOMAIN_GROUP_RID_COMPUTERS); - if (pdb_add_sam_account (sam_pwent)) { - print_user_info (name, True, False); + if (in->pdb_add_sam_account (in, sam_pwent)) { + print_user_info (in, name, True, False); } else { fprintf (stderr, "Unable to add machine! (does it already exist?)\n"); pdb_free_sam (&sam_pwent); @@ -322,7 +350,7 @@ static int new_machine (char *machinename) Delete user entry **********************************************************/ -static int delete_user_entry (char *username) +static int delete_user_entry (struct pdb_context *in, char *username) { SAM_ACCOUNT *samaccount = NULL; @@ -330,19 +358,19 @@ static int delete_user_entry (char *username) return -1; } - if (!pdb_getsampwnam(samaccount, username)) { + if (!in->pdb_getsampwnam(in, samaccount, username)) { fprintf (stderr, "user %s does not exist in the passdb\n", username); return -1; } - return pdb_delete_sam_account (samaccount); + return in->pdb_delete_sam_account (in, samaccount); } /********************************************************* Delete machine entry **********************************************************/ -static int delete_machine_entry (char *machinename) +static int delete_machine_entry (struct pdb_context *in, char *machinename) { char name[16]; SAM_ACCOUNT *samaccount = NULL; @@ -355,189 +383,12 @@ static int delete_machine_entry (char *machinename) return -1; } - if (!pdb_getsampwnam(samaccount, name)) { + if (!in->pdb_getsampwnam(in, samaccount, name)) { fprintf (stderr, "user %s does not exist in the passdb\n", name); return -1; } - return pdb_delete_sam_account (samaccount); -} - -/********************************************************* - Import smbpasswd style file -**********************************************************/ - -static int import_users (char *filename) -{ - FILE *fp = NULL; - SAM_ACCOUNT *sam_pwent = NULL; - static pstring user_name; - static unsigned char smbpwd[16]; - static unsigned char smbntpwd[16]; - char linebuf[256]; - size_t linebuf_len; - unsigned char c; - unsigned char *p; - long uidval; - int line = 0; - int good = 0; - struct passwd *pwd; - - if((fp = sys_fopen(filename, "rb")) == NULL) { - fprintf (stderr, "%s\n", strerror (ferror (fp))); - return -1; - } - - while (!feof(fp)) { - /*Get a new line*/ - linebuf[0] = '\0'; - fgets(linebuf, 256, fp); - if (ferror(fp)) { - fprintf (stderr, "%s\n", strerror (ferror (fp))); - return -1; - } - if ((linebuf_len = strlen(linebuf)) == 0) { - line++; - continue; - } - if (linebuf[linebuf_len - 1] != '\n') { - c = '\0'; - while (!ferror(fp) && !feof(fp)) { - c = fgetc(fp); - if (c == '\n') break; - } - } else - linebuf[linebuf_len - 1] = '\0'; - linebuf[linebuf_len] = '\0'; - if ((linebuf[0] == 0) && feof(fp)) { - /*end of file!!*/ - return 0; - } - line++; - if (linebuf[0] == '#' || linebuf[0] == '\0') - continue; - - /* Get user name */ - p = (unsigned char *) strchr_m(linebuf, ':'); - if (p == NULL) { - fprintf (stderr, "Error: malformed password entry at line %d !!\n", line); - continue; - } - strncpy(user_name, linebuf, PTR_DIFF(p, linebuf)); - user_name[PTR_DIFF(p, linebuf)] = '\0'; - - /* Get smb uid. */ - p++; - if(*p == '-') { - fprintf (stderr, "Error: negative uid at line %d\n", line); - continue; - } - if (!isdigit(*p)) { - fprintf (stderr, "Error: malformed password entry at line %d (uid not number)\n", line); - continue; - } - uidval = atoi((char *) p); - while (*p && isdigit(*p)) p++; - if (*p != ':') { - fprintf (stderr, "Error: malformed password entry at line %d (no : after uid)\n", line); - continue; - } - if(!(pwd = sys_getpwnam(user_name))) { - fprintf(stderr, "User %s does not \ -exist in system password file (usually /etc/passwd). Cannot add \ -account without a valid local system user.\n", user_name); - return False; - } - - if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sam_pwent, pwd))) { - fprintf(stderr, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name); - return False; - } - - /* Get passwords */ - p++; - if (*p == '*' || *p == 'X') { - /* Password deliberately invalid */ - fprintf (stderr, "Warning: entry invalidated for user %s\n", user_name); - pdb_set_lanman_passwd(sam_pwent, NULL); - pdb_set_nt_passwd(sam_pwent,NULL); - pdb_set_acct_ctrl(sam_pwent, pdb_get_acct_ctrl(sam_pwent) | ACB_DISABLED); - } else { - if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) { - fprintf (stderr, "Error: malformed password entry at line %d (password too short)\n",line); - pdb_free_sam (&sam_pwent); - continue; - } - if (p[32] != ':') { - fprintf (stderr, "Error: malformed password entry at line %d (no terminating :)\n",line); - pdb_free_sam (&sam_pwent); - continue; - } - if (!strncasecmp((char *) p, "NO PASSWORD", 11)) { - pdb_set_lanman_passwd(sam_pwent, NULL); - pdb_set_acct_ctrl(sam_pwent, pdb_get_acct_ctrl(sam_pwent) | ACB_PWNOTREQ); - } else { - if (!pdb_gethexpwd((char *)p, smbpwd)) { - fprintf (stderr, "Error: malformed Lanman password entry at line %d (non hex chars)\n", line); - pdb_free_sam (&sam_pwent); - continue; - } - pdb_set_lanman_passwd(sam_pwent, smbpwd); - } - /* NT password */ - p += 33; - if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) { - if (*p != '*' && *p != 'X') { - if (pdb_gethexpwd((char *)p,smbntpwd)) { - pdb_set_nt_passwd(sam_pwent, smbntpwd); - } - } - p += 33; - } - } - - /* Get ACCT_CTRL field if any */ - if (*p == '[') { - uint16 acct_ctrl; - unsigned char *end_p = (unsigned char *)strchr_m((char *)p, ']'); - - acct_ctrl = pdb_decode_acct_ctrl((char*)p); - if (acct_ctrl) - acct_ctrl = ACB_NORMAL; - - pdb_set_acct_ctrl(sam_pwent, acct_ctrl); - - /* Get last change time */ - if(end_p) - p = end_p + 1; - if(*p == ':') { - p++; - if(*p && (StrnCaseCmp((char *)p, "LCT-", 4)==0)) { - int i; - - p += 4; - for(i = 0; i < 8; i++) { - if(p[i] == '\0' || !isxdigit(p[i])) break; - } - if(i == 8) { - pdb_set_pass_last_set_time (sam_pwent, (time_t)strtol((char *)p, NULL, 16)); - } - } - } - } - - /* Now ADD the entry */ - if (!(pdb_add_sam_account (sam_pwent))) { - fprintf (stderr, "Unable to add user entry!\n"); - pdb_free_sam (&sam_pwent); - continue; - } - printf ("%s imported!\n", user_name); - good++; - pdb_free_sam (&sam_pwent); - } - printf ("%d lines read.\n%d entryes imported\n", line, good); - return 0; + return in->pdb_delete_sam_account (in, samaccount); } /********************************************************* @@ -546,102 +397,85 @@ account without a valid local system user.\n", user_name); int main (int argc, char **argv) { - int ch; - BOOL list_users = False; - BOOL verbose = False; - BOOL spstyle = False; - BOOL setparms = False; - BOOL machine = False; - BOOL add_user = False; - BOOL delete_user = False; - BOOL import = False; - char *user_name = NULL; - char *full_name = NULL; - char *home_dir = NULL; - char *home_drive = NULL; - char *logon_script = NULL; - char *profile_path = NULL; - char *smbpasswd = NULL; + static BOOL list_users = False; + static BOOL verbose = False; + static BOOL spstyle = False; + static BOOL setparms = False; + static BOOL machine = False; + static BOOL add_user = False; + static BOOL delete_user = False; + static BOOL import = False; + int opt; + static char *full_name = NULL; + static char *user_name = NULL; + static char *home_dir = NULL; + static char *home_drive = NULL; + static char *backend_in = NULL; + static char *backend_out = NULL; + static char *logon_script = NULL; + static char *profile_path = NULL; + static char *config_file = dyn_CONFIGFILE; + static char *new_debuglevel = NULL; + + struct pdb_context *in; + poptContext pc; + struct poptOption long_options[] = { + POPT_AUTOHELP + {"list", 'l',POPT_ARG_VAL, &list_users, 1, "list all users", NULL}, + {"verbose", 'v',POPT_ARG_VAL, &verbose, 1, "be verbose", NULL }, + {"smbpasswd-style", 'w',POPT_ARG_VAL, &spstyle, 1, "give output in smbpasswd style", NULL}, + {"user", 'u',POPT_ARG_STRING,&user_name, 0, "use username", "USER" }, + {"fullname", 'f',POPT_ARG_STRING,&full_name, 0, "set full name", NULL}, + {"homedir", 'h',POPT_ARG_STRING,&home_dir, 0, "set home directory", NULL}, + {"drive", 'd',POPT_ARG_STRING,&home_drive, 0, "set home drive", NULL}, + {"script", 's',POPT_ARG_STRING,&logon_script, 0, "set logon script", NULL}, + {"profile", 'p',POPT_ARG_STRING,&profile_path, 0, "set profile path", NULL}, + {"create", 'a',POPT_ARG_VAL,&add_user, 1, "create user", NULL}, + {"machine", 'm',POPT_ARG_VAL,&machine, 1,"account is a machine account",NULL}, + {"delete", 'x',POPT_ARG_VAL,&delete_user,1,"delete user",NULL}, + {"import", 'i',POPT_ARG_STRING,&backend_in,0,"use different passdb backend",NULL}, + {"export", 'e',POPT_ARG_STRING,&backend_out,0,"export user accounts to backend", NULL}, + {"debuglevel",'D', POPT_ARG_STRING, &new_debuglevel,0,"set debuglevel",NULL}, + {"configfile",'c',POPT_ARG_STRING, &config_file,0,"use different configuration file",NULL}, + {0,0,0,0} + }; setup_logging("pdbedit", True); - if (argc < 2) { - usage(); - return 0; + pc = poptGetContext(NULL, argc, (const char **) argv, long_options, + POPT_CONTEXT_KEEP_FIRST); + + while((opt = poptGetNextOpt(pc)) != -1); + + if (new_debuglevel){ + debug_parse_levels(new_debuglevel); + AllowDebugChange = False; } - - DEBUGLEVEL = 1; - AllowDebugChange = False; - if (!lp_load(dyn_CONFIGFILE,True,False,False)) { + if (!lp_load(config_file,True,False,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", - dyn_CONFIGFILE); + config_file); exit(1); } - - if(!initialize_password_db(True)) { - fprintf(stderr, "Can't setup password database vectors.\n"); + + + setparms = (full_name || home_dir || home_drive || logon_script || profile_path); + + if (((add_user?1:0) + (delete_user?1:0) + (list_users?1:0) + (import?1:0) + (setparms?1:0)) + (backend_out?1:0) > 1) { + fprintf (stderr, "Incompatible options on command line!\n"); exit(1); } - - while ((ch = getopt(argc, argv, "ad:f:h:i:lmp:s:u:vwxD:")) != EOF) { - switch(ch) { - case 'a': - add_user = True; - break; - case 'm': - machine = True; - break; - case 'l': - list_users = True; - break; - case 'v': - verbose = True; - break; - case 'w': - spstyle = True; - break; - case 'u': - user_name = optarg; - break; - case 'f': - setparms = True; - full_name = optarg; - break; - case 'h': - setparms = True; - home_dir = optarg; - break; - case 'd': - setparms = True; - home_drive = optarg; - break; - case 's': - setparms = True; - logon_script = optarg; - break; - case 'p': - setparms = True; - profile_path = optarg; - break; - case 'x': - delete_user = True; - break; - case 'i': - import = True; - smbpasswd = optarg; - break; - case 'D': - DEBUGLEVEL = atoi(optarg); - break; - default: - usage(); + + if (!backend_in) { + if (!NT_STATUS_IS_OK(make_pdb_context_list(&in, lp_passdb_backend()))){ + fprintf(stderr, "Can't initialize passdb backend.\n"); + return 1; + } + } else { + if (!NT_STATUS_IS_OK(make_pdb_context_string(&in, backend_in))){ + fprintf(stderr, "Can't initialize passdb backend.\n"); + return 1; } - } - if (((add_user?1:0) + (delete_user?1:0) + (list_users?1:0) + (import?1:0) + (setparms?1:0)) > 1) { - fprintf (stderr, "Incompatible options on command line!\n"); - usage(); - exit(1); } if (add_user) { @@ -650,9 +484,11 @@ int main (int argc, char **argv) return -1; } if (machine) - return new_machine (user_name); + return new_machine (in, user_name); else - return new_user (user_name, full_name, home_dir, home_drive, logon_script, profile_path); + return new_user (in, user_name, full_name, home_dir, + home_drive, logon_script, + profile_path); } if (delete_user) { @@ -661,32 +497,32 @@ int main (int argc, char **argv) return -1; } if (machine) - return delete_machine_entry (user_name); + return delete_machine_entry (in, user_name); else - return delete_user_entry (user_name); + return delete_user_entry (in, user_name); } - + if (user_name) { if (setparms) - set_user_info ( user_name, full_name, - home_dir, - home_drive, - logon_script, - profile_path); + return set_user_info (in, user_name, full_name, + home_dir, + home_drive, + logon_script, + profile_path); else - return print_user_info (user_name, verbose, spstyle); - - return 0; + return print_user_info (in, user_name, verbose, + spstyle); } - if (list_users) - return print_users_list (verbose, spstyle); - - if (import) - return import_users (smbpasswd); - - usage(); + return print_users_list (in, verbose, spstyle); - return 0; + if (backend_out) + return export_database(in, backend_out); + + poptPrintHelp(pc, stderr, 0); + + return 1; } + + diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index 017f4035b0..b6a13180a3 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -42,6 +42,9 @@ enum acl_mode {SMB_ACL_SET, SMB_ACL_DELETE, SMB_ACL_MODIFY, SMB_ACL_ADD }; enum chown_mode {REQUEST_NONE, REQUEST_CHOWN, REQUEST_CHGRP}; enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR}; +extern pstring global_myname; +extern fstring global_myworkgroup; + struct perm_value { char *perm; uint32 mask; @@ -66,24 +69,25 @@ static struct perm_value standard_values[] = { { NULL, 0 }, }; -struct cli_state lsa_cli; -POLICY_HND pol; -struct ntuser_creds creds; -BOOL got_policy_hnd; +static struct cli_state *global_hack_cli; +static POLICY_HND pol; +static BOOL got_policy_hnd; + +static struct cli_state *connect_one(char *share); /* Open cli connection and policy handle */ static BOOL cacls_open_policy_hnd(void) { - creds.pwd.null_pwd = 1; - /* Initialise cli LSA connection */ - if (!lsa_cli.initialised && - !cli_lsa_initialise(&lsa_cli, server, &creds)) { - return False; + if (!global_hack_cli) { + global_hack_cli = connect_one("IPC$"); + if (!cli_nt_session_open (global_hack_cli, PIPE_LSARPC)) { + return False; + } } - + /* Open policy handle */ if (!got_policy_hnd) { @@ -91,7 +95,7 @@ static BOOL cacls_open_policy_hnd(void) /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 so we might as well do it too. */ - if (!NT_STATUS_IS_OK(cli_lsa_open_policy(&lsa_cli, lsa_cli.mem_ctx, True, + if (!NT_STATUS_IS_OK(cli_lsa_open_policy(global_hack_cli, global_hack_cli->mem_ctx, True, GENERIC_EXECUTE_ACCESS, &pol))) { return False; } @@ -116,7 +120,7 @@ static void SidToString(fstring str, DOM_SID *sid) /* Ask LSA to convert the sid to a name */ if (!cacls_open_policy_hnd() || - !NT_STATUS_IS_OK(cli_lsa_lookup_sids(&lsa_cli, lsa_cli.mem_ctx, + !NT_STATUS_IS_OK(cli_lsa_lookup_sids(global_hack_cli, global_hack_cli->mem_ctx, &pol, 1, sid, &domains, &names, &types)) || !domains || !domains[0] || !names || !names[0]) { @@ -143,7 +147,7 @@ static BOOL StringToSid(DOM_SID *sid, const char *str) } if (!cacls_open_policy_hnd() || - !NT_STATUS_IS_OK(cli_lsa_lookup_names(&lsa_cli, lsa_cli.mem_ctx, + !NT_STATUS_IS_OK(cli_lsa_lookup_names(global_hack_cli, global_hack_cli->mem_ctx, &pol, 1, &str, &sids, &types))) { result = False; @@ -151,7 +155,6 @@ static BOOL StringToSid(DOM_SID *sid, const char *str) } sid_copy(sid, &sids[0]); - done: return result; @@ -700,80 +703,31 @@ static int cacl_set(struct cli_state *cli, char *filename, /***************************************************** return a connection to a server *******************************************************/ -struct cli_state *connect_one(char *share) +static struct cli_state *connect_one(char *share) { struct cli_state *c; - struct nmb_name called, calling; struct in_addr ip; - extern pstring global_myname; - - fstrcpy(server,share+2); - share = strchr_m(server,'\\'); - if (!share) return NULL; - *share = 0; - share++; - - zero_ip(&ip); - - make_nmb_name(&calling, global_myname, 0x0); - make_nmb_name(&called , server, 0x20); - - again: - zero_ip(&ip); - - /* have to open a new connection */ - if (!(c=cli_initialise(NULL)) || !cli_connect(c, server, &ip)) { - DEBUG(0,("Connection to %s failed\n", server)); - cli_shutdown(c); - return NULL; - } - - if (!cli_session_request(c, &calling, &called)) { - DEBUG(0,("session request to %s failed\n", called.name)); - cli_shutdown(c); - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } - return NULL; - } - - DEBUG(4,(" session request ok\n")); - - if (!cli_negprot(c)) { - DEBUG(0,("protocol negotiation failed\n")); - cli_shutdown(c); - return NULL; - } - + NTSTATUS nt_status; + zero_ip(&ip); + if (!got_pass) { char *pass = getpass("Password: "); if (pass) { pstrcpy(password, pass); + got_pass = True; } } - if (!cli_session_setup(c, username, - password, strlen(password), - password, strlen(password), - lp_workgroup())) { - DEBUG(0,("session setup failed: %s\n", cli_errstr(c))); - cli_shutdown(c); - return NULL; - } - - DEBUG(4,(" session setup ok\n")); - - if (!cli_send_tconX(c, share, "?????", - password, strlen(password)+1)) { - DEBUG(0,("tree connect failed: %s\n", cli_errstr(c))); - cli_shutdown(c); + if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname, server, + &ip, 0, + share, "?????", + username, global_myworkgroup, + password, 0))) { + return c; + } else { + DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); return NULL; } - - DEBUG(4,(" tconx ok\n")); - - return c; } @@ -811,12 +765,13 @@ You can string acls together with spaces, commas or newlines\n\ extern int optind; int opt; char *p; - struct cli_state *cli=NULL; enum acl_mode mode = SMB_ACL_SET; char *the_acl = NULL; enum chown_mode change_mode = REQUEST_NONE; int result; + struct cli_state *cli; + ctx=talloc_init(); setlinebuf(stdout); @@ -921,7 +876,7 @@ You can string acls together with spaces, commas or newlines\n\ argc -= optind; argv += optind; - + if (argc > 0) { usage(); talloc_destroy(ctx); @@ -930,12 +885,26 @@ You can string acls together with spaces, commas or newlines\n\ /* Make connection to server */ + fstrcpy(server,share+2); + share = strchr_m(server,'\\'); + if (!share) { + share = strchr_m(server,'/'); + if (!share) { + return -1; + } + } + + *share = 0; + share++; + if (!test_args) { cli = connect_one(share); if (!cli) { talloc_destroy(ctx); exit(EXIT_FAILED); } + } else { + exit(0); } all_string_sub(filename, "/", "\\", 0); @@ -960,3 +929,4 @@ You can string acls together with spaces, commas or newlines\n\ return result; } + diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index d680fa4489..65519e8888 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -3,6 +3,7 @@ program to send control messages to Samba processes Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) 2001, 2002 by Martin Pool + Copyright (C) Simo Sorce 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -33,7 +34,7 @@ static struct { {"profile", MSG_PROFILE}, {"profilelevel", MSG_REQ_PROFILELEVEL}, {"debuglevel", MSG_REQ_DEBUGLEVEL}, - {"printer-notify", MSG_PRINTER_NOTIFY}, + {"printnotify", MSG_PRINTER_NOTIFY2 }, {"close-share", MSG_SMB_FORCE_TDIS}, {"samsync", MSG_SMB_SAM_SYNC}, {"samrepl", MSG_SMB_SAM_REPL}, @@ -105,17 +106,14 @@ Prints out the current Debug level returned by MSG_DEBUGLEVEL ****************************************************************************/ void debuglevel_function(int msg_type, pid_t src, void *buf, size_t len) { - int i; - int debuglevel_class[DBGC_LAST]; - - memcpy(debuglevel_class, buf, len); - - printf("Current debug level of PID %u is %d ",(unsigned int)src, debuglevel_class[0]); - for (i=1;i<DBGC_LAST;i++) - if (debuglevel_class[i]) - printf("%s:%d ", debug_classname_from_index(i), debuglevel_class[i]); - printf("\n"); + char *levels = (char *)buf; + pstring dbgcl; + printf("Current debug levels of PID %u are:\n",(unsigned int)src); + + while(next_token(&levels, dbgcl, " ", sizeof(pstring))) + printf("%s\n", dbgcl); + got_level = True; } @@ -243,19 +241,36 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params) switch (mtype) { case MSG_DEBUG: { - struct debuglevel_message dm; + char *buf, *b; + char **p; + int dim = 0; if (!params || !params[0]) { fprintf(stderr,"MSG_DEBUG needs a parameter\n"); return(False); } - ZERO_STRUCT(dm); - if (!debug_parse_params(params, dm.debuglevel_class, dm.debuglevel_class_isset)) { - fprintf(stderr, "MSG_DEBUG error. Expected <class name>:level\n"); + /* first pass retrieve total lenght */ + for (p = params; p && *p ; p++) + dim += (strnlen(*p, 1024) +1); /* lenght + space */ + b = buf = malloc(dim); + if (!buf) { + fprintf(stderr, "Out of memory!"); return(False); - } else - send_message(dest, MSG_DEBUG, &dm, sizeof(dm), False); + } + /* now build a single string with all parameters */ + for(p = params; p && *p; p++) { + int l = strnlen(*p, 1024); + strncpy(b, *p, l); + b[l] = ' '; + b = b + l + 1; + } + b[-1] = '\0'; + + send_message(dest, MSG_DEBUG, buf, dim, False); + + free(buf); + break; } @@ -326,24 +341,106 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params) } break; - case MSG_PRINTER_NOTIFY: - if (!strequal(dest, "smbd")) { - fprintf(stderr,"printer-notify can only be sent to smbd\n"); - return(False); - } + /* Send a notification message to a printer */ + + case MSG_PRINTER_NOTIFY2: { + char *cmd; + + /* Read subcommand */ + if (!params || !params[0]) { - fprintf(stderr, "printer-notify needs a printer name\n"); - return (False); + fprintf(stderr, "Must specify subcommand:\n"); + fprintf(stderr, "\tqueuepause <printername>\n"); + fprintf(stderr, "\tqueueresume <printername>\n"); + return False; } - { - char msg[8 + sizeof(fstring)]; - SIVAL(msg,0,PRINTER_CHANGE_ALL); - SIVAL(msg,4,0); - fstrcpy(&msg[8], params[0]); - retval = send_message(dest, MSG_PRINTER_NOTIFY, msg, 8 + strlen(params[0]) + 1, False); + cmd = params[0]; + + /* Pause a print queue */ + + if (strequal(cmd, "queuepause")) { + + if (!params[1]) { + fprintf(stderr, "queuepause command requires a printer name\n"); + return False; + } + + notify_printer_status_byname(params[1], PRINTER_STATUS_PAUSED); + break; } + + /* Resume a print queue */ + + if (strequal(cmd, "queueresume")) { + + if (!params[1]) { + fprintf(stderr, "queueresume command requires a printer name\n"); + return False; + } + + notify_printer_status_byname(params[1], PRINTER_STATUS_OK); + break; + } + + /* Pause a print job */ + + if (strequal(cmd, "jobpause")) { + int jobid; + + if (!params[1] || !params[2]) { + fprintf(stderr, "jobpause command requires a printer name and a jobid\n"); + return False; + } + + jobid = atoi(params[2]); + + notify_job_status_byname( + params[1], jobid, JOB_STATUS_PAUSED, + SPOOLSS_NOTIFY_MSG_UNIX_JOBID); + } + + /* Resume a print job */ + + if (strequal(cmd, "jobresume")) { + int jobid; + + if (!params[1] || !params[2]) { + fprintf(stderr, "jobresume command requires a printer name and a jobid\n"); + return False; + } + + jobid = atoi(params[2]); + + notify_job_status_byname( + params[1], jobid, JOB_STATUS_QUEUED, + SPOOLSS_NOTIFY_MSG_UNIX_JOBID); + } + + /* Delete a print job */ + + if (strequal(cmd, "jobdelete")) { + int jobid; + + if (!params[1] || !params[2]) { + fprintf(stderr, "jobdelete command requires a printer name and a jobid\n"); + return False; + } + + jobid = atoi(params[2]); + + notify_job_status_byname( + params[1], jobid, JOB_STATUS_DELETING, + SPOOLSS_NOTIFY_MSG_UNIX_JOBID); + + notify_job_status_byname( + params[1], jobid, JOB_STATUS_DELETING| + JOB_STATUS_DELETED, + SPOOLSS_NOTIFY_MSG_UNIX_JOBID); + } + break; + } case MSG_SMB_FORCE_TDIS: if (!strequal(dest, "smbd")) { diff --git a/source3/utils/smbgroupedit.c b/source3/utils/smbgroupedit.c index cfa0dd8af9..3fdc07c2d5 100644 --- a/source3/utils/smbgroupedit.c +++ b/source3/utils/smbgroupedit.c @@ -22,7 +22,7 @@ #include "includes.h" extern pstring global_myname; -extern DOM_SID global_sam_sid; +extern pstring global_myworkgroup; /* * Next two lines needed for SunOS and don't @@ -287,14 +287,26 @@ int main (int argc, char **argv) dyn_CONFIGFILE); exit(1); } + + if (!*global_myname) { + char *p; + pstrcpy( global_myname, myhostname() ); + p = strchr_m(global_myname, '.' ); + if (p) + *p = 0; + } + + strupper(global_myname); + + fstrcpy(global_myworkgroup, lp_workgroup()); if(!initialize_password_db(True)) { fprintf(stderr, "Can't setup password database vectors.\n"); exit(1); } - if(pdb_generate_sam_sid()==False) { - printf("Can not read machine SID\n"); + if(get_global_sam_sid()==False) { + fprintf(stderr, "Can not read machine SID\n"); return 0; } diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index a96fad0cdb..70bf551edb 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -30,20 +30,13 @@ extern char *optarg; extern int optind; /* forced running in root-mode */ -static BOOL local_mode; static BOOL got_pass = False, got_username = False; -static int local_flags = 0; static BOOL stdin_passwd_get = False; static fstring user_name, user_password; -static char *new_domain = NULL; static char *new_passwd = NULL; -static char *old_passwd = NULL; static char *remote_machine = NULL; -static pstring configfile; -#ifdef WITH_LDAP_SAM static fstring ldap_secret; -#endif /********************************************************* Print command usage on stderr and die. @@ -71,9 +64,7 @@ static void usage(void) printf(" -i interdomain trust account\n"); printf(" -m machine trust account\n"); printf(" -n set no password\n"); -#ifdef WITH_LDAP_SAM printf(" -w ldap admin password\n"); -#endif printf(" -x delete user\n"); printf(" -R ORDER name resolve order\n"); @@ -88,62 +79,55 @@ static void set_line_buffering(FILE *f) /******************************************************************* Process command line options ******************************************************************/ -static void process_options(int argc, char **argv, BOOL amroot) +static int process_options(int argc, char **argv, int local_flags) { int ch; + pstring configfile; + pstrcpy(configfile, dyn_CONFIGFILE); - if (amroot) - local_flags = LOCAL_SET_PASSWORD; + local_flags |= LOCAL_SET_PASSWORD; ZERO_STRUCT(user_name); ZERO_STRUCT(user_password); user_name[0] = '\0'; - while ((ch = getopt(argc, argv, "c:axdehmnj:r:sw:R:D:U:L")) != EOF) { + while ((ch = getopt(argc, argv, "c:axdehmnjr:sw:R:D:U:L")) != EOF) { switch(ch) { case 'L': - local_mode = amroot = True; - local_flags = LOCAL_SET_PASSWORD; + local_flags |= LOCAL_AM_ROOT; break; case 'c': pstrcpy(configfile,optarg); break; case 'a': - if (!amroot) goto bad_args; local_flags |= LOCAL_ADD_USER; break; case 'x': - if (!amroot) goto bad_args; local_flags |= LOCAL_DELETE_USER; local_flags &= ~LOCAL_SET_PASSWORD; break; case 'd': - if (!amroot) goto bad_args; local_flags |= LOCAL_DISABLE_USER; local_flags &= ~LOCAL_SET_PASSWORD; break; case 'e': - if (!amroot) goto bad_args; local_flags |= LOCAL_ENABLE_USER; local_flags &= ~LOCAL_SET_PASSWORD; break; case 'm': - if (!amroot) goto bad_args; local_flags |= LOCAL_TRUST_ACCOUNT; break; case 'i': - if (!amroot) goto bad_args; local_flags |= LOCAL_INTERDOM_ACCOUNT; break; case 'j': - if (!amroot) goto bad_args; d_printf("See 'net rpc join' for this functionality\n"); exit(1); break; case 'n': - if (!amroot) goto bad_args; local_flags |= LOCAL_SET_NO_PASSWORD; + local_flags &= ~LOCAL_SET_PASSWORD; new_passwd = smb_xstrdup("NO PASSWORD"); break; case 'r': @@ -156,17 +140,10 @@ static void process_options(int argc, char **argv, BOOL amroot) stdin_passwd_get = True; break; case 'w': - if (!amroot) goto bad_args; -#ifdef WITH_LDAP_SAM local_flags |= LOCAL_SET_LDAP_ADMIN_PW; fstrcpy(ldap_secret, optarg); break; -#else - printf("-w not available unless configured --with-ldap\n"); - goto bad_args; -#endif case 'R': - if (!amroot) goto bad_args; lp_set_name_resolve_order(optarg); break; case 'D': @@ -190,7 +167,6 @@ static void process_options(int argc, char **argv, BOOL amroot) } case 'h': default: -bad_args: usage(); } } @@ -204,17 +180,21 @@ bad_args: fstrcpy(user_name, ""); break; case 1: - if (!amroot) { + if (!(local_flags & LOCAL_AM_ROOT)) { new_passwd = argv[0]; - break; + } else { + if (got_username) { + usage(); + } else { + fstrcpy(user_name, argv[0]); + } } - if (got_username) - usage(); - fstrcpy(user_name, argv[0]); break; case 2: - if (!amroot || got_username || got_pass) + if (!(local_flags & LOCAL_AM_ROOT) || got_username || got_pass) { usage(); + } + fstrcpy(user_name, argv[0]); new_passwd = smb_xstrdup(argv[1]); break; @@ -222,6 +202,13 @@ bad_args: usage(); } + if (!lp_load(configfile,True,False,False)) { + fprintf(stderr, "Can't load %s - run testparm to debug it\n", + dyn_CONFIGFILE); + exit(1); + } + + return local_flags; } /************************************************************* @@ -329,7 +316,6 @@ static BOOL password_change(const char *remote_machine, char *user_name, return ret; } -#ifdef WITH_LDAP_SAM /******************************************************************* Store the LDAP admin password in secrets.tdb ******************************************************************/ @@ -343,19 +329,18 @@ static BOOL store_ldap_admin_pw (char* pw) return secrets_store_ldap_pw(lp_ldap_admin_dn(), pw); } -#endif /************************************************************* Handle password changing for root. *************************************************************/ -static int process_root(void) +static int process_root(int local_flags) { struct passwd *pwd; int result = 0; + char *old_passwd = NULL; -#ifdef WITH_LDAP_SAM if (local_flags & LOCAL_SET_LDAP_ADMIN_PW) { printf("Setting stored password for \"%s\" in secrets.tdb\n", @@ -364,7 +349,6 @@ static int process_root(void) DEBUG(0,("ERROR: Failed to store the ldap admin password!\n")); goto done; } -#endif /* * Ensure both add/delete user are not set @@ -383,8 +367,9 @@ static int process_root(void) load_interfaces(); } - if (!user_name[0] && (pwd = sys_getpwuid(geteuid()))) { + if (!user_name[0] && (pwd = getpwuid_alloc(geteuid()))) { fstrcpy(user_name, pwd->pw_name); + passwd_free(&pwd); } if (!user_name[0]) { @@ -508,15 +493,22 @@ static int process_root(void) Handle password changing for non-root. *************************************************************/ -static int process_nonroot(void) +static int process_nonroot(int local_flags) { struct passwd *pwd = NULL; int result = 0; + char *old_passwd = NULL; + + if (local_flags & ~(LOCAL_AM_ROOT | LOCAL_SET_PASSWORD)) { + /* Extra flags that we can't honor non-root */ + usage(); + } if (!user_name[0]) { - pwd = sys_getpwuid(getuid()); + pwd = getpwuid_alloc(getuid()); if (pwd) { fstrcpy(user_name,pwd->pw_name); + passwd_free(&pwd); } else { fprintf(stderr, "smbpasswd: you don't exist - go away\n"); exit(1); @@ -570,25 +562,22 @@ static int process_nonroot(void) **********************************************************/ int main(int argc, char **argv) { - BOOL amroot = getuid() == 0; - - pstrcpy(configfile, dyn_CONFIGFILE); + int local_flags = 0; + AllowDebugChange = False; #if defined(HAVE_SET_AUTH_PARAMETERS) set_auth_parameters(argc, argv); #endif /* HAVE_SET_AUTH_PARAMETERS */ - process_options(argc, argv, amroot); + if (getuid() == 0) { + local_flags = LOCAL_AM_ROOT; + } + + local_flags = process_options(argc, argv, local_flags); setup_logging("smbpasswd", True); - if (!lp_load(configfile,True,False,False)) { - fprintf(stderr, "Can't load %s - run testparm to debug it\n", - dyn_CONFIGFILE); - exit(1); - } - /* * Set the machine NETBIOS name if not already * set from the config file. @@ -608,10 +597,10 @@ int main(int argc, char **argv) exit(1); } - if (local_mode || amroot) { + if (local_flags & LOCAL_AM_ROOT) { secrets_init(); - return process_root(); + return process_root(local_flags); } - return process_nonroot(); + return process_nonroot(local_flags); } diff --git a/source3/utils/smbtree.c b/source3/utils/smbtree.c index b80a27eb37..bcb460ee0b 100644 --- a/source3/utils/smbtree.c +++ b/source3/utils/smbtree.c @@ -87,81 +87,26 @@ static void add_name(const char *machine_name, uint32 server_type, DLIST_ADD(*name_list, new_name); } -/* Return a cli_state pointing at the IPC$ share for the given workgroup */ +/* Return a cli_state pointing at the IPC$ share for the given server */ -static struct cli_state *get_ipc_connect(char *server, +static struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, struct user_auth_info *user_info) { - struct nmb_name calling, called; - struct in_addr server_ip; struct cli_state *cli; pstring myname; - - zero_ip(&server_ip); + NTSTATUS nt_status; get_myname(myname); - - make_nmb_name(&called, myname, 0x0); - make_nmb_name(&calling, server, 0x20); - - if (is_ipaddress(server)) - if (!resolve_name(server, &server_ip, 0x20)) - return False; - - again: - if (!(cli = cli_initialise(NULL))) { - DEBUG(4, ("Unable to initialise cli structure\n")); - goto error; - } - - if (!cli_connect(cli, server, &server_ip)) { - DEBUG(4, ("Unable to connect to %s\n", server)); - goto error; - } - - if (!cli_session_request(cli, &calling, &called)) { - cli_shutdown(cli); - if (!strequal(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } - DEBUG(4, ("Session request failed to %s\n", called.name)); - goto error; - } - - if (!cli_negprot(cli)) { - DEBUG(4, ("Negprot failed\n")); - goto error; - } - - if (!cli_session_setup(cli, user_info->username, user_info->password, - strlen(user_info->password), - user_info->password, - strlen(user_info->password), server) && - /* try an anonymous login if it failed */ - !cli_session_setup(cli, "", "", 1,"", 0, server)) { - DEBUG(4, ("Session setup failed\n")); - goto error; - } - - DEBUG(4,(" session setup ok\n")); - - if (!cli_send_tconX(cli, "IPC$", "?????", - user_info->password, - strlen(user_info->password)+1)) { - DEBUG(4, ("Tconx failed\n")); - goto error; + + nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", + user_info->username, lp_workgroup(), user_info->password, + CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK); + + if (NT_STATUS_IS_OK(nt_status)) { + return cli; + } else { + return NULL; } - - return cli; - - /* Clean up after error */ - - error: - if (cli && cli->initialised) - cli_shutdown(cli); - - return NULL; } /* Return the IP address and workgroup of a master browser on the @@ -223,7 +168,7 @@ static BOOL get_workgroups(struct user_auth_info *user_info) } } - if (!(cli = get_ipc_connect(inet_ntoa(server_ip), user_info))) + if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info))) return False; if (!cli_NetServerEnum(cli, master_workgroup, @@ -248,7 +193,7 @@ static BOOL get_servers(char *workgroup, struct user_auth_info *user_info) return False; } - if (!(cli = get_ipc_connect(inet_ntoa(server_ip), user_info))) + if (!(cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info))) return False; if (!cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, add_name, @@ -262,7 +207,7 @@ static BOOL get_shares(char *server_name, struct user_auth_info *user_info) { struct cli_state *cli; - if (!(cli = get_ipc_connect(server_name, user_info))) + if (!(cli = get_ipc_connect(server_name, NULL, user_info))) return False; if (!cli_RNetShareEnum(cli, add_name, &shares)) diff --git a/source3/utils/status.c b/source3/utils/status.c index 6f4b9eb28c..b1e8bb9d8e 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -61,14 +61,14 @@ static int show_brl; /* added by OH */ -static void Ucrit_addUsername(char *username) +static void Ucrit_addUsername(const char *username) { pstrcpy(Ucrit_username, username); if(strlen(Ucrit_username) > 0) Ucrit_IsActive = 1; } -static unsigned int Ucrit_checkUsername(char *username) +static unsigned int Ucrit_checkUsername(const char *username) { if ( !Ucrit_IsActive) return 1; if (strcmp(Ucrit_username,username) ==0) return 1; @@ -544,10 +544,9 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo int main(int argc, char *argv[]) { - pstring fname; int c; static int profile_only = 0; - static int new_debuglevel = -1; + static char *new_debuglevel = NULL; TDB_CONTEXT *tdb; poptContext pc; struct poptOption long_options[] = { @@ -560,7 +559,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo {"brief", 'b', POPT_ARG_NONE, &brief}, {"profile", 'P', POPT_ARG_NONE, &profile_only}, {"byterange", 'B', POPT_ARG_NONE, &show_brl}, - {"debug", 'd', POPT_ARG_INT, &new_debuglevel}, + {"debug", 'd', POPT_ARG_STRING, &new_debuglevel}, { 0, 0, 0, 0} }; @@ -598,8 +597,8 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo return (-1); } - if (new_debuglevel != -1) { - DEBUGLEVEL = new_debuglevel; + if (new_debuglevel) { + debug_parse_levels(new_debuglevel); } if (verbose) { @@ -626,10 +625,11 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0); if (!tdb) { - d_printf("connections.tdb not initialised\n"); + d_printf("%s not initialised\n", lock_path("connections.tdb")); + d_printf("This is normal if an SMB client has never connected to your server.\n"); } else { if (verbose) { - d_printf("Opened status file %s\n", fname); + d_printf("Opened %s\n", lock_path("connections.tdb")); } if (brief) diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c index c6e417a2bc..1d48249a75 100644 --- a/source3/utils/testparm.c +++ b/source3/utils/testparm.c @@ -4,6 +4,7 @@ Copyright (C) Karl Auer 1993, 1994-1998 Extensively modified by Andrew Tridgell, 1995 + Converted to popt by Jelmer Vernooij (jelmer@nl.linux.org), 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 @@ -67,6 +68,12 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n"); ret = 1; } + if (!directory_exist(lp_piddir(), &st)) { + printf("ERROR: pid directory %s does not exist\n", + lp_piddir()); + ret = 1; + } + /* * Password server sanity checks. */ @@ -164,158 +171,126 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_ return ret; } -static void usage(char *pname) +int main(int argc, char *argv[]) { - printf("Usage: %s [-sh] [-L servername] [configfilename] [hostname hostIP]\n", pname); - printf("\t-s Suppress prompt for enter\n"); - printf("\t-h Print usage\n"); - printf("\t-L servername Set %%L macro to servername\n"); - printf("\t-t encoding Print parameters with encoding\n"); - printf("\tconfigfilename Configuration file to test\n"); - printf("\thostname hostIP. Hostname and Host IP address to test\n"); - printf("\t against \"host allow\" and \"host deny\"\n"); - printf("\n"); -} + extern char *optarg; + extern int optind; + extern fstring local_machine; + const char *config_file = dyn_CONFIGFILE; + int s; + static BOOL silent_mode = False; + int ret = 0; + int opt; + poptContext pc; + static char *term_code = ""; + static char *new_local_machine = local_machine; + const char *cname; + const char *caddr; + struct poptOption long_options[] = { + POPT_AUTOHELP + {"suppress-prompt", 's', POPT_ARG_VAL, &silent_mode, 1, "Suppress prompt for enter"}, + {"server", 'L',POPT_ARG_STRING, &new_local_machine, 0, "Set %%L macro to servername\n"}, + {"encoding", 't', POPT_ARG_STRING, &term_code, 0, "Print parameters with encoding"}, + {0,0,0,0} + }; -int main(int argc, char *argv[]) -{ - extern char *optarg; - extern int optind; - extern fstring local_machine; - pstring configfile; - int opt; - int s; - BOOL silent_mode = False; - int ret = 0; - pstring term_code; - - *term_code = 0; - - setup_logging(argv[0],True); - - while ((opt = getopt(argc, argv,"shL:t:")) != EOF) { - switch (opt) { - case 's': - silent_mode = True; - break; - case 'L': - fstrcpy(local_machine,optarg); - break; - case 'h': - usage(argv[0]); - exit(0); - break; - case 't': - pstrcpy(term_code,optarg); - break; - default: - printf("Incorrect program usage\n"); - usage(argv[0]); - exit(1); - break; - } - } - - argc += (1 - optind); - - if ((argc == 1) || (argc == 3)) - pstrcpy(configfile, dyn_CONFIGFILE); - else if ((argc == 2) || (argc == 4)) - pstrcpy(configfile,argv[optind]); - - dbf = x_stdout; - DEBUGLEVEL = 2; - AllowDebugChange = False; - - printf("Load smb config files from %s\n",configfile); - - if (!lp_load(configfile,False,True,False)) { - printf("Error loading services.\n"); - return(1); - } - - printf("Loaded services file OK.\n"); - - ret = do_global_checks(); - - for (s=0;s<1000;s++) { - if (VALID_SNUM(s)) - if (strlen(lp_servicename(s)) > 8) { - printf("WARNING: You have some share names that are longer than 8 chars\n"); - printf("These may give errors while browsing or may not be accessible\nto some older clients\n"); - break; - } - } - - for (s=0;s<1000;s++) { - if (VALID_SNUM(s)) { - char **deny_list = lp_hostsdeny(s); - char **allow_list = lp_hostsallow(s); - int i; - if(deny_list) { - for (i=0; deny_list[i]; i++) { - char *hasstar = strchr_m(deny_list[i], '*'); - char *hasquery = strchr_m(deny_list[i], '?'); - if(hasstar || hasquery) { - printf("Invalid character %c in hosts deny list (%s) for service %s.\n", - hasstar ? *hasstar : *hasquery, deny_list[i], lp_servicename(s) ); - } - } - } - - if(allow_list) { - for (i=0; allow_list[i]; i++) { - char *hasstar = strchr_m(allow_list[i], '*'); - char *hasquery = strchr_m(allow_list[i], '?'); - if(hasstar || hasquery) { - printf("Invalid character %c in hosts allow list (%s) for service %s.\n", - hasstar ? *hasstar : *hasquery, allow_list[i], lp_servicename(s) ); - } - } - } - - if(lp_level2_oplocks(s) && !lp_oplocks(s)) { - printf("Invalid combination of parameters for service %s. \ -Level II oplocks can only be set if oplocks are also set.\n", - lp_servicename(s) ); - } - } - } - - if (argc < 3) { - if (!silent_mode) { - printf("Press enter to see a dump of your service definitions\n"); - fflush(stdout); - getc(stdin); - } - lp_dump(stdout,True, lp_numservices()); - } - - if (argc >= 3) { - char *cname; - char *caddr; - - if (argc == 3) { - cname = argv[optind]; - caddr = argv[optind+1]; - } else { - cname = argv[optind+1]; - caddr = argv[optind+2]; - } - - /* this is totally ugly, a real `quick' hack */ - for (s=0;s<1000;s++) { - if (VALID_SNUM(s)) { - if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr)) { - printf("Allow connection from %s (%s) to %s\n", - cname,caddr,lp_servicename(s)); - } else { - printf("Deny connection from %s (%s) to %s\n", - cname,caddr,lp_servicename(s)); - } - } - } - } - return(ret); + pc = poptGetContext(NULL, argc, (const char **) argv, long_options, + POPT_CONTEXT_KEEP_FIRST); + + while((opt = poptGetNextOpt(pc)) != -1); + + setup_logging(poptGetArg(pc), True); + + if (poptPeekArg(pc)) + config_file = poptGetArg(pc); + + cname = poptGetArg(pc); + caddr = poptGetArg(pc); + + fstrcpy(local_machine,new_local_machine); + + dbf = x_stdout; + DEBUGLEVEL = 2; + AllowDebugChange = False; + + printf("Load smb config files from %s\n",config_file); + + if (!lp_load(config_file,False,True,False)) { + printf("Error loading services.\n"); + return(1); + } + + printf("Loaded services file OK.\n"); + + ret = do_global_checks(); + + for (s=0;s<1000;s++) { + if (VALID_SNUM(s)) + if (strlen(lp_servicename(s)) > 8) { + printf("WARNING: You have some share names that are longer than 8 chars\n"); + printf("These may give errors while browsing or may not be accessible\nto some older clients\n"); + break; + } + } + + for (s=0;s<1000;s++) { + if (VALID_SNUM(s)) { + char **deny_list = lp_hostsdeny(s); + char **allow_list = lp_hostsallow(s); + int i; + if(deny_list) { + for (i=0; deny_list[i]; i++) { + char *hasstar = strchr_m(deny_list[i], '*'); + char *hasquery = strchr_m(deny_list[i], '?'); + if(hasstar || hasquery) { + printf("Invalid character %c in hosts deny list (%s) for service %s.\n", + hasstar ? *hasstar : *hasquery, deny_list[i], lp_servicename(s) ); + } + } + } + + if(allow_list) { + for (i=0; allow_list[i]; i++) { + char *hasstar = strchr_m(allow_list[i], '*'); + char *hasquery = strchr_m(allow_list[i], '?'); + if(hasstar || hasquery) { + printf("Invalid character %c in hosts allow list (%s) for service %s.\n", + hasstar ? *hasstar : *hasquery, allow_list[i], lp_servicename(s) ); + } + } + } + + if(lp_level2_oplocks(s) && !lp_oplocks(s)) { + printf("Invalid combination of parameters for service %s. \ + Level II oplocks can only be set if oplocks are also set.\n", + lp_servicename(s) ); + } + } + } + + if (!cname) { + if (!silent_mode) { + printf("Press enter to see a dump of your service definitions\n"); + fflush(stdout); + getc(stdin); + } + lp_dump(stdout,True, lp_numservices()); + } + + if(cname && caddr){ + /* this is totally ugly, a real `quick' hack */ + for (s=0;s<1000;s++) { + if (VALID_SNUM(s)) { + if (allow_access(lp_hostsdeny(s), lp_hostsallow(s), cname, caddr)) { + printf("Allow connection from %s (%s) to %s\n", + cname,caddr,lp_servicename(s)); + } else { + printf("Deny connection from %s (%s) to %s\n", + cname,caddr,lp_servicename(s)); + } + } + } + } + return(ret); } |