diff options
author | Tim Potter <tpot@samba.org> | 2001-01-11 22:49:30 +0000 |
---|---|---|
committer | Tim Potter <tpot@samba.org> | 2001-01-11 22:49:30 +0000 |
commit | fc659e07d0cd87c9ed23d5a9b74c33bbbbd96df5 (patch) | |
tree | 69a9501848454e47456b1f5667fbfebc26f6aa85 /source3 | |
parent | d7c7283463a82ba8fd40d190c6231e398f57d466 (diff) | |
download | samba-fc659e07d0cd87c9ed23d5a9b74c33bbbbd96df5.tar.gz samba-fc659e07d0cd87c9ed23d5a9b74c33bbbbd96df5.tar.bz2 samba-fc659e07d0cd87c9ed23d5a9b74c33bbbbd96df5.zip |
Start of a rewrite of rpcclient based on the libsmb rpc client routines.
Currently there are a small selection of lsa, samr and spoolss functions
implemented. More to follow...
(This used to be commit 9a953514f2a2cfd3c43105dd6203bc3e36aff1b1)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/rpcclient/cmd_lsarpc.c | 377 | ||||
-rw-r--r-- | source3/rpcclient/cmd_samr.c | 690 | ||||
-rw-r--r-- | source3/rpcclient/cmd_spoolss.c | 1126 | ||||
-rw-r--r-- | source3/rpcclient/rpcclient.c | 359 |
4 files changed, 954 insertions, 1598 deletions
diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index bbc1e6ebdb..b6d3568668 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -1,10 +1,10 @@ /* Unix SMB/Netbios implementation. - Version 1.9. - NT Domain Authentication SMB / MSRPC client - Copyright (C) Andrew Tridgell 1994-1997 - Copyright (C) Luke Kenneth Casson Leighton 1996-1997 - + Version 2.2 + RPC pipe client + + Copyright (C) Tim Potter 2000 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -22,227 +22,296 @@ #include "includes.h" -extern FILE *out_hnd; - -/* Convert SID_NAME_USE values to strings */ - -struct sid_name { - enum SID_NAME_USE name_type; - char *name; -} sid_name_type_str[] = { - { SID_NAME_UNKNOWN, "UNKNOWN" }, - { SID_NAME_USER, "User" }, - { SID_NAME_DOM_GRP, "Domain Group" }, - { SID_NAME_DOMAIN, "Domain" }, - { SID_NAME_ALIAS, "Local Group"} , - { SID_NAME_WKN_GRP, "Well-known Group" }, - { SID_NAME_DELETED, "Deleted" }, - { SID_NAME_INVALID, "Invalid" }, - { 0, NULL } -}; +extern int DEBUGLEVEL; +extern pstring server; -static char *get_sid_name_type_str(enum SID_NAME_USE name_type) -{ - int i = 0; +/* Look up domain related information on a remote host */ - while(sid_name_type_str[i].name) { - if (name_type == sid_name_type_str[i].name_type) { - return sid_name_type_str[i].name; - } - i++; +static uint32 cmd_lsa_query_info_policy(int argc, char **argv) +{ + struct cli_state cli; + POLICY_HND pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + struct ntuser_creds creds; + BOOL got_policy_hnd = False; + DOM_SID dom_sid; + fstring sid_str, domain_name; + uint32 info_class = 3; + + if (argc > 2) { + printf("Usage: %s [info_class]\n", argv[0]); + return 0; } - return NULL; -} - -/* Look up a list of sids */ + if (argc == 2) { + info_class = atoi(argv[1]); + } + + /* Open a lsa handle */ -uint32 cmd_lsa_lookup_sids(struct client_info *info, int argc, char *argv[]) -{ - POLICY_HND lsa_pol; - fstring srv_name; - char **names; - DOM_SID *sids; - int num_sids = 0, num_names, i; - uint32 *types, result; + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); - /* Check command arguments */ + if (cli_lsa_initialise(&cli, server, &creds) == NULL) { + goto done; + } - if (argc == 1) { - fprintf(out_hnd, "lsa_lookupsids sid1 [sid2...]\n"); - return NT_STATUS_INVALID_PARAMETER; + if ((result = cli_lsa_open_policy(&cli, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol)) != NT_STATUS_NOPROBLEMO) { + goto done; } - sids = (DOM_SID *)malloc((argc - 1) * sizeof(DOM_SID)); + got_policy_hnd = True; + + /* Lookup the names */ - for (i = 1; i < argc; i++) { - if (string_to_sid(&sids[num_sids], argv[i])) { - num_sids++; - } else { - fprintf(out_hnd, "could not parse sid %s\n", argv[i]); - } + if ((result = cli_lsa_query_info_policy(&cli, &pol, info_class, + domain_name, &dom_sid)) + != NT_STATUS_NOPROBLEMO) { + goto done; } - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); + sid_to_string(sid_str, &dom_sid); - /* Lookup domain controller; receive a policy handle */ + printf("domain %s has sid %s\n", domain_name, sid_str); - result = lsa_open_policy(srv_name, &lsa_pol, True, - SEC_RIGHTS_MAXIMUM_ALLOWED); + done: - if (result != 0) { - report(out_hnd, "open policy failed: %s\n", - get_nt_error_msg(result)); - return result; + if (got_policy_hnd) { + cli_lsa_close(&cli, &pol); } - /* Send lsa lookup sids call */ + return result; +} - result = lsa_lookup_sids(&lsa_pol, num_sids, sids, &names, - &types, &num_names); +/* Resolve a list of names to a list of sids */ + +static uint32 cmd_lsa_lookup_names(int argc, char **argv) +{ + struct cli_state cli; + struct ntuser_creds creds; + POLICY_HND pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + BOOL got_policy_hnd = False; + DOM_SID *sids; + uint32 *types; + int num_names, i; - if (result != 0) { - report(out_hnd, "lookup names failed: %s\n", - get_nt_error_msg(result)); - return result; + if (argc == 1) { + printf("Usage: %s [name1 [name2 [...]]]\n", argv[0]); + return 0; } - result = lsa_close(&lsa_pol); + /* Open a lsa handle */ - if (result != 0) { - report(out_hnd, "lsa close failed: %s\n", - get_nt_error_msg(result)); - return result; + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); + + if (cli_lsa_initialise(&cli, server, &creds) == NULL) { + goto done; } - /* Print output */ + if ((result = cli_lsa_open_policy(&cli, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol)) != NT_STATUS_NOPROBLEMO) { + goto done; + } - if (names != NULL) { - report(out_hnd, "Lookup SIDS:\n"); + got_policy_hnd = True; - for (i = 0; i < num_names; i++) { - fstring temp; + /* Lookup the names */ - sid_to_string(temp, &sids[i]); + if ((result = cli_lsa_lookup_names( + &cli, &pol, argc - 1, &argv[1], &sids, &types, &num_names) != + NT_STATUS_NOPROBLEMO)) { + goto done; + } - report(out_hnd, "SID: %s -> %s (%d: %s)\n", - temp, names[i] ? names[i] : "(null)", - types[i], get_sid_name_type_str(types[i])); + /* Print results */ - if (names[i] != NULL) { - free(names[i]); - } - } + for (i = 0; i < num_names; i++) { + fstring sid_str; - free(names); + sid_to_string(sid_str, &sids[i]); + printf("%s\t\t%s (%d)\n", argv[i + 1], sid_str, + types[i]); } - if (types) { - free(types); + safe_free(sids); + safe_free(types); + + done: + + if (got_policy_hnd) { + cli_lsa_close(&cli, &pol); } return result; } -/* Look up a list of names */ +/* Resolve a list of SIDs to a list of names */ -uint32 cmd_lsa_lookup_names(struct client_info *info, int argc, char *argv[]) +static uint32 cmd_lsa_lookup_sids(int argc, char **argv) { - POLICY_HND lsa_pol; - fstring srv_name; - int num_names, i, num_sids; + struct cli_state cli; + POLICY_HND pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + struct ntuser_creds creds; + BOOL got_policy_hnd = False; DOM_SID *sids; char **names; - uint32 *types, result; - - /* Check command arguments */ + uint32 *types; + int num_names, i; if (argc == 1) { - fprintf(out_hnd, "lsa_lookupnames name1 [name2...]\n"); - return NT_STATUS_INVALID_PARAMETER; + printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]); + return 0; } - names = (char **)malloc((argc - 1) * sizeof(char *)); - num_names = argc - 1; + /* Open a lsa handle */ + + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); + + if (cli_lsa_initialise(&cli, server, &creds) == NULL) { + goto done; + } - for (i = 1; i < argc; i++) { - names[i - 1] = argv[i]; + if ((result = cli_lsa_open_policy(&cli, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol)) != NT_STATUS_NOPROBLEMO) { + goto done; } - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); + got_policy_hnd = True; - /* Lookup domain controller; receive a policy handle */ + /* Convert arguments to sids */ - result = lsa_open_policy(srv_name, &lsa_pol, True, - SEC_RIGHTS_MAXIMUM_ALLOWED); + sids = (DOM_SID *)malloc(sizeof(DOM_SID) * (argc - 1)); - if (result != 0) { - report(out_hnd, "open policy failed: %s\n", - get_nt_error_msg(result)); - return result; + if (!sids) { + printf("out of memory\n"); + goto done; } - /* Send lsa lookup names call */ + for (i = 0; i < argc - 1; i++) { + string_to_sid(&sids[i], argv[i + 1]); + } - result = lsa_lookup_names(&lsa_pol, num_names, names, &sids, - &types, &num_sids); + /* Lookup the SIDs */ - if (result != 0) { - report(out_hnd, "lookup sids failed: %s\n", - get_nt_error_msg(result)); - return result; + if ((result = cli_lsa_lookup_sids(&cli, &pol, argc - 1, sids, + &names, &types, &num_names) != + NT_STATUS_NOPROBLEMO)) { + goto done; } - result = lsa_close(&lsa_pol); + /* Print results */ + + for (i = 0; i < num_names; i++) { + fstring sid_str; - if (result != 0) { - report(out_hnd, "lsa close failed: %s\n", - get_nt_error_msg(result)); - return result; + sid_to_string(sid_str, &sids[i]); + printf("%s\t\t%s (%d)\n", sid_str, names[i] ? names[i] : + "*unknown*", types[i]); } - /* Print output */ + safe_free(sids); + safe_free(types); + + for (i = 0; i < num_names; i++) { + safe_free(names[i]); + } - if (sids != NULL) { - fstring temp; + safe_free(names); - report(out_hnd, "Lookup Names:\n"); - for (i = 0; i < num_sids; i++) { - sid_to_string(temp, &sids[i]); - report(out_hnd, "Name: %s -> %s (%d: %s)\n", - names[i], temp, types[i], - get_sid_name_type_str(types[i])); -#if 0 - if (sids[i] != NULL) { - free(sids[i]); - } -#endif - } + done: - free(sids); + if (got_policy_hnd) { + cli_lsa_close(&cli, &pol); } return result; } -/* rpcclient interface */ +/* Enumerate list of trusted domains */ -static const struct command_set lsa_commands[] = { +static uint32 cmd_lsa_enum_trust_dom(int argc, char **argv) +{ + struct cli_state cli; + POLICY_HND pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + struct ntuser_creds creds; + BOOL got_policy_hnd = False; + DOM_SID *domain_sids; + char **domain_names; + int num_domains, enum_ctx = 0, i; + + if (argc != 1) { + printf("Usage: %s\n", argv[0]); + return 0; + } - { "LSARPC", NULL, NULL, {NULL, NULL} }, + /* Open a lsa handle */ - { "lsa_lookup_sids", cmd_lsa_lookup_sids }, - { "lsa_lookup_names", cmd_lsa_lookup_names }, + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); - {"", NULL, NULL, {NULL, NULL}} -}; + if (cli_lsa_initialise(&cli, server, &creds) == NULL) { + goto done; + } + if ((result = cli_lsa_open_policy(&cli, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol)) != NT_STATUS_NOPROBLEMO) { + goto done; + } -void add_lsa_commands(void) -{ - add_command_set(lsa_commands); + got_policy_hnd = True; + + /* Lookup list of trusted domains */ + + if ((result = cli_lsa_enum_trust_dom(&cli, &pol, &enum_ctx, + &num_domains, &domain_names, + &domain_sids) + != NT_STATUS_NOPROBLEMO)) { + goto done; + } + + /* Print results */ + + for (i = 0; i < num_domains; i++) { + fstring sid_str; + + sid_to_string(sid_str, &domain_sids[i]); + printf("%s\t\t%s\n", domain_names[i] ? domain_names[i] : + "*unknown*", sid_str); + } + + safe_free(domain_sids); + + for (i = 0; i < num_domains; i++) { + safe_free(domain_names[i]); + } + + safe_free(domain_names); + + done: + + if (got_policy_hnd) { + cli_lsa_close(&cli, &pol); + } + + return result; } + +/* List of commands exported by this module */ + +struct cmd_set lsarpc_commands[] = { + { "lsaquery", cmd_lsa_query_info_policy, "Query info policy" }, + { "lookupsids", cmd_lsa_lookup_sids, "Convert SIDs to names" }, + { "lookupnames", cmd_lsa_lookup_names, "Convert names to SIDs" }, + { "enumtrust", cmd_lsa_enum_trust_dom, "Enumerate trusted domains" }, + { NULL, NULL, NULL } +}; diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index c6397654be..d38aec3994 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -1,10 +1,10 @@ /* Unix SMB/Netbios implementation. - Version 1.9. - NT Domain Authentication SMB / MSRPC client - Copyright (C) Andrew Tridgell 1994-1997 - Copyright (C) Luke Kenneth Casson Leighton 1996-1997 - + Version 2.2 + RPC pipe client + + Copyright (C) Tim Potter 2000 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -20,666 +20,70 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#ifdef SYSLOG -#undef SYSLOG -#endif - #include "includes.h" extern int DEBUGLEVEL; +extern pstring server; -#define DEBUG_TESTING - -extern struct cli_state *smb_cli; - -extern FILE* out_hnd; - - -/**************************************************************************** -SAM password change -****************************************************************************/ -void cmd_sam_ntchange_pwd(struct client_info *info) -{ - fstring srv_name; - fstring domain; - fstring sid; - char *new_passwd; - BOOL res = True; - char nt_newpass[516]; - uchar nt_hshhash[16]; - uchar nt_newhash[16]; - uchar nt_oldhash[16]; - char lm_newpass[516]; - uchar lm_newhash[16]; - uchar lm_hshhash[16]; - uchar lm_oldhash[16]; - - sid_to_string(sid, &info->dom.level5_sid); - fstrcpy(domain, info->dom.level5_dom); - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - fprintf(out_hnd, "SAM NT Password Change\n"); - -#if 0 - struct pwd_info new_pwd; - pwd_read(&new_pwd, "New Password (ONCE: this is test code!):", True); -#endif - new_passwd = (char*)getpass("New Password (ONCE ONLY - get it right :-)"); - - nt_lm_owf_gen(new_passwd, lm_newhash, nt_newhash); - pwd_get_lm_nt_16(&(smb_cli->pwd), lm_oldhash, nt_oldhash ); - make_oem_passwd_hash(nt_newpass, new_passwd, nt_oldhash, True); - make_oem_passwd_hash(lm_newpass, new_passwd, lm_oldhash, True); - E_old_pw_hash(lm_newhash, lm_oldhash, lm_hshhash); - E_old_pw_hash(lm_newhash, nt_oldhash, nt_hshhash); - - cli_nt_set_ntlmssp_flgs(smb_cli, - NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_OEM | - NTLMSSP_NEGOTIATE_SIGN | - NTLMSSP_NEGOTIATE_SEAL | - NTLMSSP_NEGOTIATE_LM_KEY | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_ALWAYS_SIGN | - NTLMSSP_NEGOTIATE_00001000 | - NTLMSSP_NEGOTIATE_00002000); - - /* open SAMR session. */ - res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False; - -#if 0 - /* establish a connection. */ - res = res ? do_samr_get_dom_pwinfo(smb_cli, srv_name) : False; - - /* establish a connection. */ - res = res ? do_samr_chgpasswd_user(smb_cli, - srv_name, smb_cli->user_name, - nt_newpass, nt_hshhash, - lm_newpass, lm_hshhash) : False; -#endif - /* close the session */ - cli_nt_session_close(smb_cli); - - if (res) - { - fprintf(out_hnd, "NT Password changed OK\n"); - } - else - { - fprintf(out_hnd, "NT Password change FAILED\n"); - } -} - - -/**************************************************************************** -experimental SAM encryted rpc test connection -****************************************************************************/ -void cmd_sam_test(struct client_info *info) -{ - fstring srv_name; - fstring domain; - fstring sid; - BOOL res = True; - - sid_to_string(sid, &info->dom.level5_sid); - fstrcpy(domain, info->dom.level5_dom); - -/* - if (strlen(sid) == 0) - { - fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); - return; - } -*/ - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - fprintf(out_hnd, "SAM Encryption Test\n"); - - cli_nt_set_ntlmssp_flgs(smb_cli, - NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_OEM | - NTLMSSP_NEGOTIATE_SIGN | - NTLMSSP_NEGOTIATE_SEAL | - NTLMSSP_NEGOTIATE_LM_KEY | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_ALWAYS_SIGN | - NTLMSSP_NEGOTIATE_00001000 | - NTLMSSP_NEGOTIATE_00002000); - - /* open SAMR session. */ - res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False; - -#if 0 - /* establish a connection. */ - res = res ? do_samr_get_dom_pwinfo(smb_cli, srv_name) : False; -#endif - - /* close the session */ - cli_nt_session_close(smb_cli); - - if (res) - { - DEBUG(5,("cmd_sam_test: succeeded\n")); - } - else - { - DEBUG(5,("cmd_sam_test: failed\n")); - } -} - - -/**************************************************************************** -experimental SAM users enum. -****************************************************************************/ -void cmd_sam_enum_users(struct client_info *info) +static uint32 cmd_samr_connect(int argc, char **argv) { - fstring srv_name; - fstring domain; - fstring sid; - DOM_SID sid1; - int user_idx; - BOOL res = True; - BOOL request_user_info = False; - BOOL request_group_info = False; - uint16 num_entries = 0; - uint16 unk_0 = 0x0; - uint16 acb_mask = 0; - uint16 unk_1 = 0x0; - uint32 admin_rid = 0x304; /* absolutely no idea. */ - fstring tmp; - - sid_to_string(sid, &info->dom.level5_sid); - fstrcpy(domain, info->dom.level5_dom); - - if (strlen(sid) == 0) - { - fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); - return; - } - - init_dom_sid(&sid1, sid); - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - /* a bad way to do token parsing... */ - if (next_token(NULL, tmp, NULL, sizeof(tmp))) - { - request_user_info |= strequal(tmp, "-u"); - request_group_info |= strequal(tmp, "-g"); - } - - if (next_token(NULL, tmp, NULL, sizeof(tmp))) - { - request_user_info |= strequal(tmp, "-u"); - request_group_info |= strequal(tmp, "-g"); - } - -#ifdef DEBUG_TESTING - if (next_token(NULL, tmp, NULL, sizeof(tmp))) - { - num_entries = (uint16)strtol(tmp, (char**)NULL, 16); - } - - if (next_token(NULL, tmp, NULL, sizeof(tmp))) - { - unk_0 = (uint16)strtol(tmp, (char**)NULL, 16); - } - - if (next_token(NULL, tmp, NULL, sizeof(tmp))) - { - acb_mask = (uint16)strtol(tmp, (char**)NULL, 16); - } + struct cli_state cli; + POLICY_HND pol, domain_pol, user_pol; + uint32 result = NT_STATUS_UNSUCCESSFUL; + struct ntuser_creds creds; + BOOL got_policy_hnd = False, got_domain_hnd = False; + DOM_SID sid; - if (next_token(NULL, tmp, NULL, sizeof(tmp))) - { - unk_1 = (uint16)strtol(tmp, (char**)NULL, 16); + if (argc > 1) { + printf("Usage: %s\n", argv[0]); + return 0; } -#endif - fprintf(out_hnd, "SAM Enumerate Users\n"); - fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n", - info->myhostname, srv_name, domain, sid); + /* Open a sam handle */ -#ifdef DEBUG_TESTING - DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n", - num_entries, unk_0, acb_mask, unk_1)); -#endif + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); - /* open SAMR session. negotiate credentials */ - res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False; - - /* establish a connection. */ - res = res ? do_samr_connect(smb_cli, - srv_name, 0x00000020, - &info->dom.samr_pol_connect) : False; - - /* connect to the domain */ - res = res ? do_samr_open_domain(smb_cli, - &info->dom.samr_pol_connect, admin_rid, &sid1, - &info->dom.samr_pol_open_domain) : False; - - /* read some users */ - res = res ? do_samr_enum_dom_users(smb_cli, - &info->dom.samr_pol_open_domain, - num_entries, unk_0, acb_mask, unk_1, 0xffff, - &info->dom.sam, &info->dom.num_sam_entries) : False; - - if (res && info->dom.num_sam_entries == 0) - { - fprintf(out_hnd, "No users\n"); + if (cli_samr_initialise(&cli, server, &creds) == NULL) { + goto done; } - if (request_user_info || request_group_info) - { - /* query all the users */ - user_idx = 0; - - while (res && user_idx < info->dom.num_sam_entries) - { - uint32 user_rid = info->dom.sam[user_idx].smb_userid; - SAM_USER_INFO_21 usr; - - fprintf(out_hnd, "User RID: %8x User Name: %s\n", - user_rid, - info->dom.sam[user_idx].acct_name); - - if (request_user_info) - { - /* send user info query, level 0x15 */ - if (get_samr_query_userinfo(smb_cli, - &info->dom.samr_pol_open_domain, - 0x15, user_rid, &usr)) - { - display_sam_user_info_21(out_hnd, ACTION_HEADER , &usr); - display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr); - display_sam_user_info_21(out_hnd, ACTION_FOOTER , &usr); - } - } - - if (request_group_info) - { - uint32 num_groups; - DOM_GID gid[LSA_MAX_GROUPS]; - - /* send user group query */ - if (get_samr_query_usergroups(smb_cli, - &info->dom.samr_pol_open_domain, - user_rid, &num_groups, gid)) - { - display_group_rid_info(out_hnd, ACTION_HEADER , num_groups, gid); - display_group_rid_info(out_hnd, ACTION_ENUMERATE, num_groups, gid); - display_group_rid_info(out_hnd, ACTION_FOOTER , num_groups, gid); - } - } - - user_idx++; - } + if ((result = cli_samr_connect(&cli, server, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &pol)) != NT_STATUS_NOPROBLEMO) { + goto done; } - res = res ? do_samr_close(smb_cli, - &info->dom.samr_pol_open_domain) : False; + got_policy_hnd = True; - res = res ? do_samr_close(smb_cli, - &info->dom.samr_pol_connect) : False; + string_to_sid(&sid, "S-1-5-21-1067277791-1719175008-3000797951"); - /* close the session */ - cli_nt_session_close(smb_cli); - - if (info->dom.sam != NULL) - { - free(info->dom.sam); - } - - if (res) - { - DEBUG(5,("cmd_sam_enum_users: succeeded\n")); + if ((result = cli_samr_open_domain(&cli, &pol, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &sid, &domain_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; } - else - { - DEBUG(5,("cmd_sam_enum_users: failed\n")); - } -} - - -/**************************************************************************** -experimental SAM user query. -****************************************************************************/ -void cmd_sam_query_user(struct client_info *info) -{ - fstring srv_name; - fstring domain; - fstring sid; - DOM_SID sid1; - int user_idx = 0; /* FIXME maybe ... */ - BOOL res = True; - uint32 admin_rid = 0x304; /* absolutely no idea. */ - fstring rid_str ; - fstring info_str; - uint32 user_rid = 0; - uint32 info_level = 0x15; - - SAM_USER_INFO_21 usr; - sid_to_string(sid, &info->dom.level5_sid); - fstrcpy(domain, info->dom.level5_dom); + got_domain_hnd = True; - if (strlen(sid) == 0) - { - fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); - return; + if ((result = cli_samr_open_user(&cli, &domain_pol, + SEC_RIGHTS_MAXIMUM_ALLOWED, 500, + &user_pol)) + != NT_STATUS_NOPROBLEMO) { + goto done; } - init_dom_sid(&sid1, sid); +done: + if (got_domain_hnd) cli_samr_close(&cli, &domain_pol); + if (got_policy_hnd) cli_samr_close(&cli, &pol); - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - if (next_token(NULL, rid_str , NULL, sizeof(rid_str )) && - next_token(NULL, info_str, NULL, sizeof(info_str))) - { - user_rid = (uint32)strtol(rid_str , (char**)NULL, 16); - info_level = (uint32)strtol(info_str, (char**)NULL, 10); - } - - fprintf(out_hnd, "SAM Query User: rid %x info level %d\n", - user_rid, info_level); - fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n", - info->myhostname, srv_name, domain, sid); - - /* open SAMR session. negotiate credentials */ - res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False; - - /* establish a connection. */ - res = res ? do_samr_connect(smb_cli, - srv_name, 0x00000020, - &info->dom.samr_pol_connect) : False; - - /* connect to the domain */ - res = res ? do_samr_open_domain(smb_cli, - &info->dom.samr_pol_connect, admin_rid, &sid1, - &info->dom.samr_pol_open_domain) : False; - - fprintf(out_hnd, "User RID: %8x User Name: %s\n", - user_rid, - info->dom.sam[user_idx].acct_name); - - /* send user info query, level */ - if (get_samr_query_userinfo(smb_cli, - &info->dom.samr_pol_open_domain, - info_level, user_rid, &usr)) - { - if (info_level == 0x15) - { - display_sam_user_info_21(out_hnd, ACTION_HEADER , &usr); - display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr); - display_sam_user_info_21(out_hnd, ACTION_FOOTER , &usr); - } - } - - res = res ? do_samr_close(smb_cli, - &info->dom.samr_pol_connect) : False; - - res = res ? do_samr_close(smb_cli, - &info->dom.samr_pol_open_domain) : False; - - /* close the session */ - cli_nt_session_close(smb_cli); - - if (res) - { - DEBUG(5,("cmd_sam_query_user: succeeded\n")); - } - else - { - DEBUG(5,("cmd_sam_query_user: failed\n")); - } -} - - -/**************************************************************************** -experimental SAM groups query. -****************************************************************************/ -void cmd_sam_query_groups(struct client_info *info) -{ - fstring srv_name; - fstring domain; - fstring sid; - DOM_SID sid1; - BOOL res = True; - fstring info_str; - uint32 switch_value = 2; - uint32 admin_rid = 0x304; /* absolutely no idea. */ - - sid_to_string(sid, &info->dom.level5_sid); - fstrcpy(domain, info->dom.level5_dom); - - if (strlen(sid) == 0) - { - fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); - return; - } - - init_dom_sid(&sid1, sid); - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - if (next_token(NULL, info_str, NULL, sizeof(info_str))) - { - switch_value = (uint32)strtol(info_str, (char**)NULL, 10); - } - - fprintf(out_hnd, "SAM Query Groups: info level %d\n", switch_value); - fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n", - info->myhostname, srv_name, domain, sid); - - /* open SAMR session. negotiate credentials */ - res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False; - - /* establish a connection. */ - res = res ? do_samr_connect(smb_cli, - srv_name, 0x00000020, - &info->dom.samr_pol_connect) : False; - - /* connect to the domain */ - res = res ? do_samr_open_domain(smb_cli, - &info->dom.samr_pol_connect, admin_rid, &sid1, - &info->dom.samr_pol_open_domain) : False; - - /* send a samr 0x8 command */ - res = res ? do_samr_query_dom_info(smb_cli, - &info->dom.samr_pol_open_domain, switch_value) : False; - - res = res ? do_samr_close(smb_cli, - &info->dom.samr_pol_connect) : False; - - res = res ? do_samr_close(smb_cli, - &info->dom.samr_pol_open_domain) : False; - - /* close the session */ - cli_nt_session_close(smb_cli); - - if (res) - { - DEBUG(5,("cmd_sam_query_groups: succeeded\n")); - } - else - { - DEBUG(5,("cmd_sam_query_groups: failed\n")); - } -} - - -/**************************************************************************** -experimental SAM aliases query. -****************************************************************************/ -void cmd_sam_enum_aliases(struct client_info *info) -{ - fstring srv_name; - fstring domain; - fstring sid; - DOM_SID sid1; - BOOL res = True; - BOOL request_user_info = False; - BOOL request_alias_info = False; - uint32 admin_rid = 0x304; /* absolutely no idea. */ - fstring tmp; - - uint32 num_aliases = 3; - uint32 alias_rid[3] = { DOMAIN_GROUP_RID_ADMINS, DOMAIN_GROUP_RID_USERS, DOMAIN_GROUP_RID_GUESTS }; - fstring alias_names [3]; - uint32 num_als_usrs[3]; - - sid_to_string(sid, &info->dom.level3_sid); - fstrcpy(domain, info->dom.level3_dom); -#if 0 - fstrcpy(sid , "S-1-5-20"); -#endif - if (strlen(sid) == 0) - { - fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); - return; - } - - init_dom_sid(&sid1, sid); - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - /* a bad way to do token parsing... */ - if (next_token(NULL, tmp, NULL, sizeof(tmp))) - { - request_user_info |= strequal(tmp, "-u"); - request_alias_info |= strequal(tmp, "-g"); - } - - if (next_token(NULL, tmp, NULL, sizeof(tmp))) - { - request_user_info |= strequal(tmp, "-u"); - request_alias_info |= strequal(tmp, "-g"); - } - - fprintf(out_hnd, "SAM Enumerate Aliases\n"); - fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n", - info->myhostname, srv_name, domain, sid); - - /* open SAMR session. negotiate credentials */ - res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False; - - /* establish a connection. */ - res = res ? do_samr_connect(smb_cli, - srv_name, 0x00000020, - &info->dom.samr_pol_connect) : False; - - /* connect to the domain */ - res = res ? do_samr_open_domain(smb_cli, - &info->dom.samr_pol_connect, admin_rid, &sid1, - &info->dom.samr_pol_open_domain) : False; - -#if 0 - /* send a query on the aliase */ - res = res ? do_samr_query_lookup_rids(smb_cli, - &info->dom.samr_pol_open_domain, admin_rid, num_aliases, alias_rid, - &num_aliases, alias_names, num_als_usrs) : False; -#endif - - if (res) - { - display_alias_name_info(out_hnd, ACTION_HEADER , num_aliases, alias_names, num_als_usrs); - display_alias_name_info(out_hnd, ACTION_ENUMERATE, num_aliases, alias_names, num_als_usrs); - display_alias_name_info(out_hnd, ACTION_FOOTER , num_aliases, alias_names, num_als_usrs); - } - -#if 0 - - /* read some users */ - res = res ? do_samr_enum_dom_users(smb_cli, - &info->dom.samr_pol_open_domain, - num_entries, unk_0, acb_mask, unk_1, 0xffff, - info->dom.sam, &info->dom.num_sam_entries) : False; - - if (res && info->dom.num_sam_entries == 0) - { - fprintf(out_hnd, "No users\n"); - } - - if (request_user_info || request_alias_info) - { - /* query all the users */ - user_idx = 0; - - while (res && user_idx < info->dom.num_sam_entries) - { - uint32 user_rid = info->dom.sam[user_idx].smb_userid; - SAM_USER_INFO_21 usr; - - fprintf(out_hnd, "User RID: %8x User Name: %s\n", - user_rid, - info->dom.sam[user_idx].acct_name); - - if (request_user_info) - { - /* send user info query, level 0x15 */ - if (get_samr_query_userinfo(smb_cli, - &info->dom.samr_pol_open_domain, - 0x15, user_rid, &usr)) - { - display_sam_user_info_21(out_hnd, ACTION_HEADER , &usr); - display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr); - display_sam_user_info_21(out_hnd, ACTION_FOOTER , &usr); - } - } - - if (request_alias_info) - { - uint32 num_aliases; - DOM_GID gid[LSA_MAX_GROUPS]; - - /* send user aliase query */ - if (get_samr_query_useraliases(smb_cli, - &info->dom.samr_pol_open_domain, - user_rid, &num_aliases, gid)) - { - display_alias_info(out_hnd, ACTION_HEADER , num_aliases, gid); - display_alias_info(out_hnd, ACTION_ENUMERATE, num_aliases, gid); - display_alias_info(out_hnd, ACTION_FOOTER , num_aliases, gid); - } - } - - user_idx++; - } - } -#endif - - res = res ? do_samr_close(smb_cli, - &info->dom.samr_pol_connect) : False; - - res = res ? do_samr_close(smb_cli, - &info->dom.samr_pol_open_domain) : False; - - /* close the session */ - cli_nt_session_close(smb_cli); - - if (res) - { - DEBUG(5,("cmd_sam_enum_users: succeeded\n")); - } - else - { - DEBUG(5,("cmd_sam_enum_users: failed\n")); - } + return result; } +/* List of commands exported by this module */ +struct cmd_set samr_commands[] = { + { "samconnect", cmd_samr_connect, "Test" }, + { NULL, NULL, NULL } +}; diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 58ee1ca0c1..6beec447de 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1,12 +1,12 @@ /* Unix SMB/Netbios implementation. - Version 1.9. - NT Domain Authentication SMB / MSRPC client - Copyright (C) Andrew Tridgell 1994-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Jean-Francois Micouleau 1999-2000 - Copyright (C) Gerald Carter 2000 - + Version 2.2 + RPC pipe client + + Copyright (C) Tim Potter 2000 + Copyright (C) Andrew Tridgell 1992-1999 + Copyright (C) Luke Kenneth Casson Leighton 1996-1999 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -23,868 +23,430 @@ */ #include "includes.h" -#include "nterr.h" -#include "rpc_parse.h" -#include "rpc_client.h" -#include "rpcclient.h" extern int DEBUGLEVEL; -#define DEBUG_TESTING - -extern FILE* out_hnd; - -extern struct user_creds *usr_creds; +extern pstring server; +extern pstring global_myname; +extern pstring username, password; +extern pstring workgroup; /**************************************************************************** -function to do the mapping between the long architecture name and -the short one. -****************************************************************************/ -static BOOL get_short_archi(char *short_archi, char *long_archi) + display sec_ace structure + ****************************************************************************/ +static void display_sec_ace(SEC_ACE *ace) { - struct table { - char *long_archi; - char *short_archi; - }; - - struct table archi_table[]= - { - {"Windows 4.0", "WIN40" }, - {"Windows NT x86", "W32X86" }, - {"Windows NT R4000", "W32MIPS" }, - {"Windows NT Alpha_AXP", "W32ALPHA" }, - {"Windows NT PowerPC", "W32PPC" }, - {NULL, "" } - }; - - int i=-1; - - DEBUG(107,("Getting architecture dependant directory\n")); - do { - i++; - } while ( (archi_table[i].long_archi!=NULL ) && - StrCaseCmp(long_archi, archi_table[i].long_archi) ); - - if (archi_table[i].long_archi==NULL) { - DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi)); - return FALSE; - } - - StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi)); - - DEBUGADD(108,("index: [%d]\n", i)); - DEBUGADD(108,("long architecture: [%s]\n", long_archi)); - DEBUGADD(108,("short architecture: [%s]\n", short_archi)); - - return TRUE; -} + fstring sid_str; -/**************************************************************************** -nt spoolss query -****************************************************************************/ -uint32 cmd_spoolss_enum_printers(struct client_info *info, int argc, char *argv[]) -{ - PRINTER_INFO_CTR ctr; - - uint32 flags; - uint32 level = 1; + sid_to_string(sid_str, &ace->sid); + printf("\t\tSID: %s\n", sid_str); - fstring srv_name; - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - flags=PRINTER_ENUM_LOCAL; - report (out_hnd, "Flags = PRINTER_ENUM_LOCAL\n"); - if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr)) - DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); - - - flags=PRINTER_ENUM_NAME; - report (out_hnd, "Flags = PRINTER_ENUM_NAME\n"); - if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr)) - DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); - - flags=PRINTER_ENUM_SHARED|PRINTER_ENUM_NAME; - report (out_hnd, "Flags = PRINTER_ENUM_SHARED|PRINTER_ENUM_NAME\n"); - if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr)) - DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); - - flags=PRINTER_ENUM_CONNECTIONS; - report (out_hnd, "Flags = PRINTER_ENUM_CONNECTIONS\n"); - if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr)) - DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); - - flags=PRINTER_ENUM_NETWORK; - report (out_hnd, "Flags = PRINTER_ENUM_NETWORK\n"); - if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr)) - DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); - - flags=PRINTER_ENUM_REMOTE; - report (out_hnd, "Flags = PRINTER_ENUM_REMOTE\n"); - if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr)) - DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); - - return NT_STATUS_NOPROBLEMO; + printf("\t\ttype:[%d], flags:[0x%02x], mask:[0x%08x]\n", + ace->type, ace->flags, ace->info.mask); } /**************************************************************************** -nt spoolss query -****************************************************************************/ -uint32 cmd_spoolss_enum_ports(struct client_info *info, int argc, char *argv[]) + display sec_acl structure + ****************************************************************************/ +static void display_sec_acl(SEC_ACL *acl) { - PORT_INFO_CTR ctr; - uint32 level; - fstring srv_name; - - if (argc < 2) - { - report (out_hnd, "spoolenumports <level>\n"); - return NT_STATUS_INVALID_PARAMETER; - } + if (acl->size != 0 && acl->num_aces != 0) { + int i; - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - level = atoi(argv[1]); - - if (msrpc_spoolss_enum_ports(srv_name, level, &ctr)) - DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); - - return NT_STATUS_NOPROBLEMO; + printf("\t\tRevision:[%d]\n", acl->revision); + for (i = 0; i < acl->num_aces; i++) { + display_sec_ace(&acl->ace[i]); + } + } } /**************************************************************************** -nt spoolss query -****************************************************************************/ -uint32 cmd_spoolss_enum_printerdata(struct client_info *info, int argc, char *argv[]) + display sec_desc structure + ****************************************************************************/ +static void display_sec_desc(SEC_DESC *sec) { - fstring srv_name; - fstring station; - char *printer_name; - - if (argc < 2) { - report(out_hnd, "spoolenumdata <printer name>\n"); - return NT_STATUS_INVALID_PARAMETER; - } - - printer_name = argv[1]; + fstring sid_str; - fstrcpy(station, "\\\\"); - fstrcat(station, info->myhostname); - strupper(station); + printf("\tRevision:[%d]\n", sec->revision); - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - if (!strnequal("\\\\", printer_name, 2)) - { - fstrcat(srv_name, "\\"); - fstrcat(srv_name, printer_name); - printer_name = srv_name; + if (sec->off_owner_sid) { + sid_to_string(sid_str, sec->owner_sid); + printf("\tOwner SID: %s\n", sid_str); } - DEBUG(0,("spoolenumdata - printer: %s station: %s user: %s\n", printer_name, station, usr_creds->ntc.user_name)); - - if (msrpc_spoolss_enum_printerdata( printer_name, station, - usr_creds->ntc.user_name)) - { - DEBUG(0,("cmd_spoolss_enum_printerdata: query succeeded\n")); - return NT_STATUS_NOPROBLEMO; + if (sec->off_grp_sid) { + sid_to_string(sid_str, sec->grp_sid); + printf("\tGroup SID: %s\n", sid_str); } - report(out_hnd, "FAILED\n"); - return NT_STATUS_UNSUCCESSFUL; + + if (sec->off_sacl) display_sec_acl(sec->sacl); + if (sec->off_dacl) display_sec_acl(sec->dacl); } /**************************************************************************** -nt spoolss query +printer info level 0 display function ****************************************************************************/ -uint32 cmd_spoolss_getprinter(struct client_info *info, int argc, char *argv[]) +static void display_print_info_0(PRINTER_INFO_0 *i1) { - PRINTER_INFO_CTR ctr; - fstring srv_name; - fstring station; - char *printer_name; - uint32 level; - - if (argc < 2) { - report(out_hnd, "spoolgetprinter <printer name>\n"); - return NT_STATUS_INVALID_PARAMETER; - } - - printer_name = argv[1]; - - fstrcpy(station, "\\\\"); - fstrcat(station, info->myhostname); - strupper(station); - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - if (!strnequal("\\\\", printer_name, 2)) - { - fstrcat(srv_name, "\\"); - fstrcat(srv_name, printer_name); - printer_name = srv_name; - } - - if (argc < 4) - level=2; - else - level = atoi(argv[2]); - - if (msrpc_spoolss_getprinter(printer_name, level, station, "Administrator", ctr)) - DEBUG(5,("cmd_spoolss_getprinter: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); - - return NT_STATUS_NOPROBLEMO; -} + fstring name; + fstring the_server; + unistr_to_ascii(name, i1->printername.buffer, sizeof(name) - 1); + unistr_to_ascii(server, i1->servername.buffer, sizeof(the_server) - 1); -static void display_spool_job_info_ctr( const char* printer_name, - const char* station, - uint32 level, - uint32 num, void *const *const ctr) -{ - display_job_info_ctr(out_hnd, ACTION_HEADER , level, num, ctr); - display_job_info_ctr(out_hnd, ACTION_ENUMERATE, level, num, ctr); - display_job_info_ctr(out_hnd, ACTION_FOOTER , level, num, ctr); + printf("\tprintername:[%s]\n", name); + printf("\tservername:[%s]\n", the_server); + printf("\tcjobs:[0x%x]\n", i1->cjobs); + printf("\ttotal_jobs:[0x%x]\n", i1->total_jobs); + + printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i1->year, i1->month, + i1->day, i1->dayofweek); + printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i1->hour, i1->minute, + i1->second, i1->milliseconds); + + printf("\tglobal_counter:[0x%x]\n", i1->global_counter); + printf("\ttotal_pages:[0x%x]\n", i1->total_pages); + + printf("\tmajorversion:[0x%x]\n", i1->major_version); + printf("\tbuildversion:[0x%x]\n", i1->build_version); + + printf("\tunknown7:[0x%x]\n", i1->unknown7); + printf("\tunknown8:[0x%x]\n", i1->unknown8); + printf("\tunknown9:[0x%x]\n", i1->unknown9); + printf("\tsession_counter:[0x%x]\n", i1->session_counter); + printf("\tunknown11:[0x%x]\n", i1->unknown11); + printf("\tprinter_errors:[0x%x]\n", i1->printer_errors); + printf("\tunknown13:[0x%x]\n", i1->unknown13); + printf("\tunknown14:[0x%x]\n", i1->unknown14); + printf("\tunknown15:[0x%x]\n", i1->unknown15); + printf("\tunknown16:[0x%x]\n", i1->unknown16); + printf("\tchange_id:[0x%x]\n", i1->change_id); + printf("\tunknown18:[0x%x]\n", i1->unknown18); + printf("\tstatus:[0x%x]\n", i1->status); + printf("\tunknown20:[0x%x]\n", i1->unknown20); + printf("\tc_setprinter:[0x%x]\n", i1->c_setprinter); + printf("\tunknown22:[0x%x]\n", i1->unknown22); + printf("\tunknown23:[0x%x]\n", i1->unknown23); + printf("\tunknown24:[0x%x]\n", i1->unknown24); + printf("\tunknown25:[0x%x]\n", i1->unknown25); + printf("\tunknown26:[0x%x]\n", i1->unknown26); + printf("\tunknown27:[0x%x]\n", i1->unknown27); + printf("\tunknown28:[0x%x]\n", i1->unknown28); + printf("\tunknown29:[0x%x]\n", i1->unknown29); } /**************************************************************************** -nt spoolss query +printer info level 1 display function ****************************************************************************/ -uint32 cmd_spoolss_enum_jobs(struct client_info *info, int argc, char *argv[]) +static void display_print_info_1(PRINTER_INFO_1 *i1) { - fstring srv_name; - fstring station; - char *printer_name; - - void **ctr = NULL; - uint32 level = 1; - - if (argc < 2) { - report(out_hnd, "spooljobs <printer name>\n"); - return NT_STATUS_INVALID_PARAMETER; - } - - printer_name = argv[1]; - - fstrcpy(station, "\\\\"); - fstrcat(station, info->myhostname); - strupper(station); - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - if (!strnequal("\\\\", printer_name, 2)) - { - fstrcat(srv_name, "\\"); - fstrcat(srv_name, printer_name); - printer_name = srv_name; - } - - DEBUG(4,("spoolopen - printer: %s station: %s user: %s\n", printer_name, - station, usr_creds->ntc.user_name)); - - if (msrpc_spoolss_enum_jobs( printer_name, station, - usr_creds->ntc.user_name, - level, &ctr, display_spool_job_info_ctr)) - { - DEBUG(5,("cmd_spoolss_enum_jobs: query succeeded\n")); - return NT_STATUS_NOPROBLEMO; - } - report(out_hnd, "FAILED\n"); - return NT_STATUS_UNSUCCESSFUL; + fstring desc; + fstring name; + fstring comm; + + unistr_to_ascii(desc, i1->description.buffer, sizeof(desc) - 1); + unistr_to_ascii(name, i1->name .buffer, sizeof(name) - 1); + unistr_to_ascii(comm, i1->comment .buffer, sizeof(comm) - 1); + + printf("\tflags:[0x%x]\n", i1->flags); + printf("\tname:[%s]\n", name); + printf("\tdescription:[%s]\n", desc); + printf("\tcomment:[%s]\n\n", comm); } /**************************************************************************** -nt spoolss query +printer info level 2 display function ****************************************************************************/ -uint32 cmd_spoolss_open_printer_ex(struct client_info *info, int argc, char *argv[]) +static void display_print_info_2(PRINTER_INFO_2 *i2) { - fstring srv_name; - fstring station; - char *printer_name; - POLICY_HND hnd; - - BOOL res = True; - - if (argc < 2) - { - report(out_hnd, "spoolopen <printer name>\n"); - return NT_STATUS_INVALID_PARAMETER; - } - - printer_name = argv[1]; - - fstrcpy(station, "\\\\"); - fstrcat(station, info->myhostname); - strupper(station); - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - if (!strnequal("\\\\", printer_name, 2)) - { - fstrcat(srv_name, "\\"); - fstrcat(srv_name, printer_name); - printer_name = srv_name; - } - - DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n", - printer_name, station, usr_creds->ntc.user_name)); - - res = res ? spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS, - station, "Administrator", &hnd) : False; - - res = res ? spoolss_closeprinter(&hnd) : False; - - if (res) - { - DEBUG(5,("cmd_spoolss_open_printer_ex: query succeeded\n")); - report(out_hnd, "OK\n"); - return NT_STATUS_NOPROBLEMO; - } - DEBUG(5,("cmd_spoolss_open_printer_ex: query failed\n")); - return NT_STATUS_UNSUCCESSFUL; + fstring servername; + fstring printername; + fstring sharename; + fstring portname; + fstring drivername; + fstring comment; + fstring location; + fstring sepfile; + fstring printprocessor; + fstring datatype; + fstring parameters; + + unistr_to_ascii(servername, i2->servername.buffer, + sizeof(servername) - 1); + unistr_to_ascii(printername, i2->printername.buffer, + sizeof(printername) - 1); + unistr_to_ascii(sharename, i2->sharename.buffer, + sizeof(sharename) - 1); + unistr_to_ascii(portname, i2->portname.buffer, sizeof(portname) - 1); + unistr_to_ascii(drivername, i2->drivername.buffer, + sizeof(drivername) - 1); + unistr_to_ascii(comment, i2->comment.buffer, sizeof(comment) - 1); + unistr_to_ascii(location, i2->location.buffer, sizeof(location) - 1); + unistr_to_ascii(sepfile, i2->sepfile.buffer, sizeof(sepfile) - 1); + unistr_to_ascii(printprocessor, i2->printprocessor.buffer, + sizeof(printprocessor) - 1); + unistr_to_ascii(datatype, i2->datatype.buffer, sizeof(datatype) - 1); + unistr_to_ascii(parameters, i2->parameters.buffer, + sizeof(parameters) - 1); + + printf("\tservername:[%s]\n", servername); + printf("\tprintername:[%s]\n", printername); + printf("\tsharename:[%s]\n", sharename); + printf("\tportname:[%s]\n", portname); + printf("\tdrivername:[%s]\n", drivername); + printf("\tcomment:[%s]\n", comment); + printf("\tlocation:[%s]\n", location); + printf("\tsepfile:[%s]\n", sepfile); + printf("\tprintprocessor:[%s]\n", printprocessor); + printf("\tdatatype:[%s]\n", datatype); + printf("\tparameters:[%s]\n", parameters); + printf("\tattributes:[0x%x]\n", i2->attributes); + printf("\tpriority:[0x%x]\n", i2->priority); + printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority); + printf("\tstarttime:[0x%x]\n", i2->starttime); + printf("\tuntiltime:[0x%x]\n", i2->untiltime); + printf("\tstatus:[0x%x]\n", i2->status); + printf("\tcjobs:[0x%x]\n", i2->cjobs); + printf("\taverageppm:[0x%x]\n", i2->averageppm); + + if (i2->secdesc) display_sec_desc(i2->secdesc); } /**************************************************************************** -nt spoolss query +printer info level 3 display function ****************************************************************************/ -uint32 cmd_spoolss_getprinterdata(struct client_info *info, int argc, char *argv[]) +static void display_print_info_3(PRINTER_INFO_3 *i3) { - fstring srv_name; - fstring station; - char *printer_name; - char *value_name; - - NEW_BUFFER ctr; - uint32 status; - uint32 type = 1; - - if (argc < 3) { - report(out_hnd, "spoolgetdata <printer name> <value name>\n"); - return NT_STATUS_INVALID_PARAMETER; - } - - printer_name = argv[1]; - value_name = argv[2]; - - fstrcpy(station, "\\\\"); - fstrcat(station, info->myhostname); - strupper(station); - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - if (!strnequal("\\\\", printer_name, 2)) - { - fstrcat(srv_name, "\\"); - fstrcat(srv_name, printer_name); - printer_name = srv_name; - } - - DEBUG(4,("spoolgetdata - printer: %s station: %s value: %s\n", - printer_name, station, value_name)); - - status = msrpc_spoolss_getprinterdata( printer_name, station, - /* "Administrateur", */ - usr_creds->ntc.user_name, - value_name, &type, - &ctr, NULL); - - if (status == NT_STATUS_NOPROBLEMO) - { - DEBUG(5,("cmd_spoolss_getprinterdata: query succeeded\n")); - } - else - { - report(out_hnd, "FAILED\n"); - } - - return status; -} + printf("\tflags:[0x%x]\n", i3->flags); -/**************************************************************************** -nt spoolss query -****************************************************************************/ -uint32 cmd_spoolss_getprinterdriver(struct client_info *info, int argc, char *argv[]) -{ - PRINTER_DRIVER_CTR ctr; - fstring srv_name; - fstring station; - char *printer_name; - fstring environment; - uint32 level; - - if (argc < 2) { - report(out_hnd, "spoolgetprinterdriver <printer name>\n"); - return NT_STATUS_INVALID_PARAMETER; - } - - printer_name = argv[1]; - - fstrcpy(station, "\\\\"); - fstrcat(station, info->myhostname); - strupper(station); - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - if (!strnequal("\\\\", printer_name, 2)) - { - fstrcat(srv_name, "\\"); - fstrcat(srv_name, printer_name); - printer_name = srv_name; - } - - report (out_hnd, "Environment = Windows NT x86\n"); - fstrcpy(environment, "Windows NT x86"); - level=3; - if (msrpc_spoolss_getprinterdriver(printer_name, environment, level, station, "Administrator", ctr)) - DEBUG(5,("cmd_spoolss_getprinterdriver: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); - - report (out_hnd, "Environment = Windows 4.0\n"); - fstrcpy(environment, "Windows 4.0"); - level=3; - if (msrpc_spoolss_getprinterdriver(printer_name, environment, level, station, "Administrator", ctr)) - DEBUG(5,("cmd_spoolss_getprinterdriver: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); - - return NT_STATUS_NOPROBLEMO; + display_sec_desc(i3->secdesc); } -/**************************************************************************** -nt spoolss query -****************************************************************************/ -uint32 cmd_spoolss_enumprinterdrivers(struct client_info *info, int argc, char *argv[]) +/* Enumerate printers */ + +static uint32 cmd_spoolss_enum_printers(int argc, char **argv) { - PRINTER_DRIVER_CTR ctr; - fstring srv_name; - fstring environment; - uint32 level; + uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1; + struct cli_state cli; + struct ntuser_creds creds; + PRINTER_INFO_CTR ctr; + int returned; + + if (argc > 2) { + printf("Usage: enumprinters\n"); + return NT_STATUS_NOPROBLEMO; + } + + if (argc == 2) { + info_level = atoi(argv[1]); + } + + /* Initialise RPC connection */ - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); - fstrcpy(environment, "Windows NT x86"); - level=3; + if (cli_spoolss_initialise(&cli, server, &creds) == NULL) { + goto done; + } + + /* Enumerate printers */ + + ZERO_STRUCT(ctr); - if (msrpc_spoolss_enumprinterdrivers(srv_name, environment, level, ctr)) - DEBUG(5,("cmd_spoolss_enumprinterdrivers: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); + result = cli_spoolss_enum_printers(&cli, PRINTER_ENUM_LOCAL, + info_level, &returned, &ctr); - return NT_STATUS_NOPROBLEMO; + if (result == NT_STATUS_NOPROBLEMO) { + switch(info_level) { + case 0: + display_print_info_0(ctr.printers_0); + break; + case 1: + display_print_info_1(ctr.printers_1); + break; + case 2: + display_print_info_2(ctr.printers_2); + break; + case 3: + display_print_info_3(ctr.printers_3); + break; + default: + printf("unknown info level %d\n", info_level); + break; + } + } + + done: + return result; } /**************************************************************************** -nt spoolss query +port info level 1 display function ****************************************************************************/ -uint32 cmd_spoolss_getprinterdriverdir(struct client_info *info, int argc, char *argv[]) +static void display_port_info_1(PORT_INFO_1 *i1) { - DRIVER_DIRECTORY_CTR ctr; - int i; + fstring buffer; + + unistr_to_ascii(buffer, i1->port_name.buffer, sizeof(buffer)-1); + printf("\tPort Name:\t[%s]\n", buffer); +} - uint32 level = 1; +/**************************************************************************** +port info level 2 display function +****************************************************************************/ +static void display_port_info_2(PORT_INFO_2 *i2) +{ + fstring buffer; + + unistr_to_ascii(buffer, i2->port_name.buffer, sizeof(buffer) - 1); + printf("\tPort Name:\t[%s]\n", buffer); + unistr_to_ascii(buffer, i2->monitor_name.buffer, sizeof(buffer) - 1); + printf("\tMonitor Name:\t[%s]\n", buffer); + unistr_to_ascii(buffer, i2->description.buffer, sizeof(buffer) - 1); + printf("\tDescription:\t[%s]\n", buffer); + printf("\tPort Type:\t[%d]\n", i2->port_type); + printf("\tReserved:\t[%d]\n", i2->reserved); + printf("\n"); +} - fstring srv_name; - fstring env; +/* Enumerate ports */ - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); +static uint32 cmd_spoolss_enum_ports(int argc, char **argv) +{ + uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1; + struct cli_state cli; + struct ntuser_creds creds; + PORT_INFO_CTR ctr; + int returned; + + if (argc == 1 || argc < 2) { + printf("Usage: enumports [level]\n"); + return NT_STATUS_NOPROBLEMO; + } - if (argc < 2) { - report(out_hnd, "spoolgetprinterdriverdir <arch>\n"); - return NT_STATUS_NOPROBLEMO; - } + if (argc == 2) { + info_level = atoi(argv[1]); + } - fstrcpy(env, argv[1]); + /* Initialise RPC connection */ - for (i=3; i<=argc; i++) { - fstrcat(env, " "); - fstrcat(env, argv[i]); - } + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); - if (msrpc_spoolss_getprinterdriverdir(srv_name, env, level, ctr)) - DEBUG(5,("cmd_spoolss_getprinterdriverdir: query succeeded\n")); - else - report(out_hnd, "FAILED\n"); + if (cli_spoolss_initialise(&cli, server, &creds) == NULL) { + goto done; + } - return NT_STATUS_NOPROBLEMO; -} + /* Enumerate printers */ -/******************************************************************************** - send an AddPrinterEx() request -********************************************************************************/ -uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]) -{ - fstring srv_name, - printer_name, - driver_name, - port_name, - share_name; - POLICY_HND hnd; - PRINTER_INFO_2 print_info_2; - PORT_INFO_1 *port_info_1 = NULL; - NEW_BUFFER buffer; - uint32 status, - needed, - returned; - uint32 i; - fstring srv_port_name; - BOOL valid_port = False; - TALLOC_CTX *mem_ctx = NULL; - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - /* check (and copy) the command line arguments */ - if (argc < 5) { - report(out_hnd, "spooladdprinterex <name> <shared name> <driver> <port>\n"); - return NT_STATUS_INVALID_PARAMETER; - } - else - { - fstrcpy(printer_name, argv[1]); - fstrcpy(share_name, argv[2]); - fstrcpy(driver_name, argv[3]); - fstrcpy(port_name, argv[4]); - } - - /* Verify that the specified port is ok; spoolss_enum_ports() should - be a level 1 since all we need is the name */ - if ((mem_ctx=talloc_init()) == NULL) - { - DEBUG(0, ("cmd_spoolss_addprinterex: talloc_init() failed!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - init_buffer (&buffer, 0, mem_ctx); - - /* send a NULL buffer first */ - status=spoolss_enum_ports(srv_name, 1, &buffer, 0, - &needed, &returned); - - /* send the right amount of space this time */ - if (status==ERROR_INSUFFICIENT_BUFFER) { - init_buffer(&buffer, needed, mem_ctx); - status=spoolss_enum_ports(srv_name, 1, &buffer, - needed, &needed, &returned); - - /* if the call succeeded, then decode the buffer into - an PRINTER_INFO_1 structre */ - if (status == NT_STATUS_NO_PROBLEMO) - { - decode_port_info_1(&buffer, returned, &port_info_1); - } - else - { - report (out_hnd, "cmd_spoolss_addprinterex: FAILED to enumerate ports\n"); - return NT_STATUS_NOPROBLEMO; - } - } - - /* - * now we have an array of port names and we can interate - * through it to verify port_name before actually attempting - * to add the printer on the server. - */ - for (i=0; i<returned; i++) - { - /* compare port_info_1[i].port_name to the port_name specified */ - unistr_to_ascii(srv_port_name, port_info_1[i].port_name.buffer, - sizeof(srv_port_name)-1); - if (strequal(srv_port_name, port_name)) - { - valid_port = True; + ZERO_STRUCT(ctr); + + result = cli_spoolss_enum_ports(&cli, info_level, &returned, &ctr); + + if (result == NT_STATUS_NOPROBLEMO) { + int i; + + for (i = 0; i < returned; i++) { + switch (info_level) { + case 1: + display_port_info_1(&ctr.port.info_1[i]); break; + case 2: + display_port_info_2(&ctr.port.info_2[i]); + break; + default: + printf("unknown info level %s\n", info_level); + break; + } } } - if (!valid_port) - { - report (out_hnd, "cmd_spoolss_addprinterex: Invalid port specified!\n"); - return NT_STATUS_NOPROBLEMO; - } - - /* - * Need to build the PRINTER_INFO_2 struct here. - * I think it would be better only to deal with a PRINTER_INFO_2 - * and the abstract the creation of a SPOOL_PRINTER_INFO_LEVEL_2 - * from that rather than dealing with the struct passed directly - * on the wire. We don't need the extra *_ptr fields, etc... - * here anyways. --jerry - */ - ZERO_STRUCTP(&print_info_2); - /* init_unistr( &print_info_2.servername, srv_name); */ - init_unistr( &print_info_2.printername, printer_name); - init_unistr( &print_info_2.sharename, share_name); - init_unistr( &print_info_2.portname, port_name); - init_unistr( &print_info_2.drivername, driver_name); - init_unistr( &print_info_2.comment, "Created by rpcclient"); - init_unistr( &print_info_2.printprocessor, "winprint"); - init_unistr( &print_info_2.datatype, "RAW"); - print_info_2.devmode = NULL; - print_info_2.secdesc = NULL; - print_info_2.attributes = PRINTER_ATTRIBUTE_SHARED; - print_info_2.priority = 0; - print_info_2.defaultpriority = 0; - print_info_2.starttime = 0; - print_info_2.untiltime = 0; - - /* These three fields must not be used by AddPrinter() - as defined in the MS Platform SDK documentation.. --jerry - print_info_2.status = 0; - print_info_2.cjobs = 0; - print_info_2.averageppm = 0; - */ - - - /* if successful, spoolss_addprinterex() should return True and hnd - should be a valid handle to an open printer */ - if (spoolss_addprinterex(&hnd, srv_name, &print_info_2)) - { - DEBUG(0,("cmd_spoolss_addprinterex: [%s] added successfully.\n", printer_name)); - if (!spoolss_closeprinter( &hnd )) - { - report (out_hnd, "cmd_spoolss_addprinterex: spoolss_closeprinter FAILED!\n"); - } - } - else - { - report (out_hnd, "cmd_spoolss_addprinterex: spoolss_addprinterex FAILED!\n"); - } - - return NT_STATUS_NOPROBLEMO; + done: + return result; } - -/******************************************************************************** - send an AddPrinterDriver() request -********************************************************************************/ -uint32 cmd_spoolss_addprinterdriver(struct client_info *info, int argc, char *argv[]) -{ - PRINTER_DRIVER_CTR driver_info; - DRIVER_INFO_3 info3; - fstring arch; - fstring srv_name; - uint32 result = NT_STATUS_NO_PROBLEMO; - - /* parse the command arguements */ - if (argc < 3) - { - report (out_hnd, "spooladdprinterdriver <arch>\\\n"); - report (out_hnd, "\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n"); - report (out_hnd, "\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n"); - report (out_hnd, "\t<Default Data Type>:<Comma Separated list of Files>\n"); - - return NT_STATUS_INVALID_PARAMETER; - } - else - { - ZERO_STRUCT(info3); - - /* get the enviorment for the driver */ - if (!get_short_archi(arch, argv[1])) - { - report (out_hnd, "Unknown architechture [%s]\n", argv[1]); - return NT_STATUS_INVALID_PARAMETER; - - } - else - { - set_drv_info_3_env(&info3, arch); - } - - /* fill in the other struct members */ - if (!init_drv_info_3_members(&info3, argv[2])) - { - report (out_hnd, "Invalid parameter list.\n"); - return NT_STATUS_INVALID_PARAMETER; - } - } - - /* get the server name */ - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, info->dest_host); - strupper(srv_name); - - /* call AddPrinterDriver() woth an info level 3 */ - driver_info.info3 = &info3; - if ((result=spoolss_addprinterdriver(srv_name, 3, &driver_info)) != NT_STATUS_NO_PROBLEMO) - { - report( out_hnd, "spoolss_addprinterdriver: Add Printer failed [%d]\n", - result); - } - else - { - fstring driver_name; - unistr_to_ascii (driver_name, info3.name.buffer, sizeof(driver_name)-1); - report( out_hnd, "cmd_spoolss_addprinterdriver: Printer Driver [%s] added successfully\n", driver_name); - } - - free_drv_info_3(&info3); - - return result; -} -/******************************************************************************* - set the version and environment fields of a DRIVER_INFO_3 struct - ******************************************************************************/ -void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch) +/* Get printer information */ + +static uint32 cmd_spoolss_getprinter(int argc, char **argv) { - if (strcmp(arch, "WIN40") == 0) - { - info->version = 0; - init_unistr(&info->architecture, "Windows 4.0"); - } - else if (strcmp(arch, "W32X86") == 0) - { - info->version = 2; - init_unistr(&info->architecture, "Windows NT x86"); - } - else if (strcmp(arch, "W32MIPS") == 0) - { - info->version = 2; - init_unistr(&info->architecture, "Windows NT R4000"); - } - else if (strcmp(arch, "W32ALPHA") == 0) - { - info->version = 2; - init_unistr(&info->architecture, "Windows NT Alpha_AXP"); - } - else if (strcmp(arch, "W32PPC") == 0) - { - info->version = 2; - init_unistr(&info->architecture, "Windows NT PowerPC"); - } - else - { - DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch)); + struct cli_state cli; + POLICY_HND pol; + uint32 result, info_level = 1; + BOOL opened_hnd = False; + struct ntuser_creds creds; + PRINTER_INFO_CTR ctr; + int *returned; + + if (argc == 1 || argc > 3) { + printf("Usage: %s printername [level]\n", argv[0]); + return NT_STATUS_NOPROBLEMO; } - - return; -} -/************************************************************************** - wrapper for strtok to get the next parameter from a delimited list. - Needed to handle the empty parameter string denoted by "NULL" - *************************************************************************/ -static char* get_driver_3_param (char* str, char* delim, UNISTR* dest) -{ - char *ptr; + /* Initialise RPC connection */ - /* get the next token */ - ptr = strtok(str, delim); + ZERO_STRUCT(cli); + init_rpcclient_creds(&creds); - /* a string of 'NULL' is used to represent an empty - parameter because two consecutive delimiters - will not return an empty string. See man strtok(3) - for details */ - if (StrCaseCmp(ptr, "NULL") == 0) - ptr = NULL; + if (cli_spoolss_initialise(&cli, server, &creds) == NULL) { + goto done; + } - if (dest != NULL) - init_unistr(dest, ptr); + /* Open a printer handle */ - return ptr; -} + if (argc == 3) { + info_level = atoi(argv[2]); + } -/******************************************************************************** - fill in the members of a DRIVER_INFO_3 struct using a character - string in the form of - <Long Printer Name>:<Driver File Name>:<Data File Name>:\ - <Config File Name>:<Help File Name>:<Language Monitor Name>:\ - <Default Data Type>:<Comma Separated list of Files> - *******************************************************************************/ -BOOL init_drv_info_3_members (DRIVER_INFO_3 *info, char *args) -{ - char *str, *str2; - uint32 len, i; - - /* fill in the UNISTR fields */ - str = get_driver_3_param (args, ":", &info->name); - str = get_driver_3_param (NULL, ":", &info->driverpath); - str = get_driver_3_param (NULL, ":", &info->datafile); - str = get_driver_3_param (NULL, ":", &info->configfile); - str = get_driver_3_param (NULL, ":", &info->helpfile); - str = get_driver_3_param (NULL, ":", &info->monitorname); - str = get_driver_3_param (NULL, ":", &info->defaultdatatype); - - /* <Comma Separated List of Dependent Files> */ - str2 = get_driver_3_param (NULL, ":", NULL); /* save the beginning of the string */ - str = str2; - - /* begin to strip out each filename */ - str = strtok(str, ","); - len = 0; - while (str != NULL) - { - /* keep a cumlative count of the str lengths */ - len += strlen(str)+1; - str = strtok(NULL, ","); + if ((result = cli_spoolss_open_printer_ex( + &cli, argv[1], "", PRINTER_ALL_ACCESS, global_myname, + username, &pol)) != NT_STATUS_NOPROBLEMO) { + goto done; } - /* allocate the space; add one extra slot for a terminating NULL. - Each filename is NULL terminated and the end contains a double - NULL */ - if ((info->dependentfiles=(uint16*)malloc((len+1)*sizeof(uint16))) == NULL) - { - DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n")); - return False; + opened_hnd = True; + + /* Get printer info */ + + if ((result = cli_spoolss_getprinter(&cli, &pol, info_level, &ctr)) + != NT_STATUS_NOPROBLEMO) { + goto done; } - for (i=0; i<len; i++) - { - info->dependentfiles[i] = (uint16)str2[i]; + + /* Display printer info */ + + switch (info_level) { + case 0: + display_print_info_0(ctr.printers_0); + break; + case 1: + display_print_info_1(ctr.printers_1); + break; + case 2: + display_print_info_2(ctr.printers_2); + break; + case 3: + display_print_info_3(ctr.printers_3); + break; + default: + printf("unknown info level %d\n", info_level); + break; } - info->dependentfiles[len] = '\0'; - return True; -} + done: + if (opened_hnd) cli_spoolss_closeprinter(&cli, &pol); + cli_spoolss_shutdown(&cli); -/***************************************************************************** - free any dynamically allocated members - ****************************************************************************/ -void free_drv_info_3 (DRIVER_INFO_3 *info) -{ - if (info->dependentfiles != NULL) - { - free(info->dependentfiles); - info->dependentfiles = NULL; - } - - return; + return result; } +/* List of commands exported by this module */ + +struct cmd_set spoolss_commands[] = { + { "enumprinters", cmd_spoolss_enum_printers, "Enumerate printers" }, + { "enumports", cmd_spoolss_enum_ports, "Enumerate printer ports" }, + { "getprinter", cmd_spoolss_getprinter, "Get printer info" }, + { NULL, NULL, NULL } +}; diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 6de9363b72..56dd4d1854 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -1,10 +1,10 @@ /* Unix SMB/Netbios implementation. - Version 1.9. - SMB client - Copyright (C) Andrew Tridgell 1994-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - + Version 2.2 + RPC pipe client + + Copyright (C) Tim Potter 2000 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -21,23 +21,344 @@ */ #include "includes.h" -#include "ntdomain.h" -#include "rpcclient.h" + +extern int DEBUGLEVEL; + +pstring password; +pstring username; +pstring workgroup; +pstring server; + +/* Various pipe commands */ + +extern struct cmd_set lsarpc_commands[]; +extern struct cmd_set samr_commands[]; +extern struct cmd_set spoolss_commands[]; + +/* Initialise client credentials for authenticated pipe access */ + +void init_rpcclient_creds(struct ntuser_creds *creds) +{ + ZERO_STRUCTP(creds); + + if (lp_encrypted_passwords()) { + pwd_make_lm_nt_16(&creds->pwd, password); + } else { + pwd_set_cleartext(&creds->pwd, password); + } + + fstrcpy(creds->user_name, username); + fstrcpy(creds->domain, workgroup); +} + +/* List to hold groups of commands */ + +static struct cmd_list { + struct cmd_list *prev, *next; + struct cmd_set *cmd_set; +} *cmd_list; + +static uint32 cmd_help(int argc, char **argv) +{ + struct cmd_list *temp_list; + + for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) { + struct cmd_set *temp_set = temp_list->cmd_set; + + while(temp_set->name) { + printf("%s\t%s\n", temp_set->name, + temp_set->description); + temp_set++; + } + } + + return 0; +} + +static uint32 cmd_debuglevel(int argc, char **argv) +{ + if (argc > 2) { + printf("Usage: %s [debuglevel]\n", argv[0]); + return NT_STATUS_NOPROBLEMO; + } + + if (argc == 2) { + DEBUGLEVEL = atoi(argv[1]); + } + + printf("debuglevel is %d\n", DEBUGLEVEL); + + return NT_STATUS_NOPROBLEMO; +} + +/* Build in rpcclient commands */ + +static struct cmd_set rpcclient_commands[] = { + { "help", cmd_help, "Print list of commands" }, + { "debuglevel", cmd_debuglevel, "Set debug level" }, + { "?", cmd_help, "Print list of commands" }, + + { NULL, NULL, NULL } +}; + +void add_command_set(struct cmd_set *cmd_set) +{ + struct cmd_list *entry; + + if (!(entry = (struct cmd_list *)malloc(sizeof(struct cmd_list)))) { + DEBUG(0, ("out of memory\n")); + return; + } + + ZERO_STRUCTP(entry); + + entry->cmd_set = cmd_set; + DLIST_ADD(cmd_list, entry); +} + +static uint32 do_cmd(struct cmd_set *cmd_entry, char *cmd) +{ + char *p = cmd, **argv = NULL; + uint32 result; + pstring buf; + int argc = 0, i; + + next_token(&p, buf, " ", sizeof(buf)); + + /* Count number of arguments first time through the loop then + allocate memory and strdup them. */ + + again: + while(next_token(NULL, buf, " ", sizeof(buf))) { + if (argv) { + argv[argc] = strdup(buf); + } + + argc++; + } + + if (!argv) { + + /* Create argument list */ + + argv = (char **)malloc(sizeof(char *) * argc); + if (!argv) { + fprintf(stderr, "out of memoryx\n"); + return 0; + } + + argc = 1; + p = cmd; + next_token(&p, buf, " ", sizeof(buf)); + argv[0] = strdup(buf); + + goto again; + } + + /* Call the function */ + + result = cmd_entry->fn(argc, argv); + + /* Cleanup */ + + for (i = 0; i < argc; i++) { + free(argv[i]); + } + + free(argv); + + return result; +} + +/* Process a command entered at the prompt or as part of -c */ + +static uint32 process_cmd(char *cmd) +{ + struct cmd_list *temp_list; + BOOL found = False; + pstring buf; + char *p = cmd; + uint32 result; + + if (!next_token(&p, buf, " ", sizeof(buf))) { + return 0; + } + + /* Search for matching commands */ + + for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) { + struct cmd_set *temp_set = temp_list->cmd_set; + + while(temp_set->name) { + if (strequal(buf, temp_set->name)) { + found = True; + result = do_cmd(temp_set, cmd); + goto done; + } + temp_set++; + } + } + + done: + if (!found) { + printf("command not found: %s\n", buf); + return 0; + } + + if (result != 0) { + printf("result was %s\n", get_nt_error_msg(result)); + } + + return result; + +} + +/* Print usage information */ + +static void usage(char *pname) +{ + printf("Usage: %s server [options]\n", pname); + + printf("\t-N don't ask for a password\n"); + printf("\t-d debuglevel set the debuglevel\n"); + printf("\t-h Print this help message.\n"); + printf("\t-U username set the network username\n"); + printf("\t-W workgroup set the workgroup name\n"); + printf("\t-c command string execute semicolon separated cmds\n"); + printf("\n"); +} + +/* Main function */ int main(int argc, char *argv[]) { - add_lsa_commands(); -#if 0 - add_net_commands(); - add_evt_commands(); - add_sam_commands(); - add_svc_commands(); - add_reg_commands(); - add_ntl_commands(); - add_at_commands(); - add_dfs_commands(); + extern char *optarg; + extern int optind; + struct in_addr dest_ip; + BOOL got_pass = False; + BOOL have_ip = False; + int opt; + pstring cmdstr, servicesf = CONFIGFILE; + extern FILE *dbf; + + setlinebuf(stdout); + dbf = stderr; + + setup_logging(argv[0], True); + +#ifdef HAVE_LIBREADLINE + /* Allow conditional parsing of the ~/.inputrc file. */ + rl_readline_name = "smbclient"; +#endif + + DEBUGLEVEL = 2; + + TimeInit(); + charset_initialise(); + + /* Parse options */ + + if (argc < 2) { + usage(argv[0]); + return 0; + } + + pstrcpy(server, argv[1]); + + argv++; + argc--; + + while ((opt = getopt(argc, argv, "s:Nd:I:U:W:c:")) != EOF) { + switch (opt) { + case 's': + pstrcpy(servicesf, optarg); + break; + case 'N': + got_pass = True; + break; + case 'd': + DEBUGLEVEL = atoi(optarg); + break; + case 'I': + dest_ip = *interpret_addr2(optarg); + have_ip = True; + break; + case 'U': { + char *lp; + pstrcpy(username,optarg); + if ((lp=strchr(username,'%'))) { + *lp = 0; + pstrcpy(password,lp+1); + got_pass = True; + memset(strchr(optarg,'%')+1,'X',strlen(password)); + } + break; + } + case 'W': + pstrcpy(workgroup, optarg); + break; + case 'c': + pstrcpy(cmdstr, optarg); + got_pass = True; + break; + case 'h': + default: + usage(argv[0]); + exit(1); + } + } + + /* Load smb.conf file */ + + if (!lp_load(servicesf,True,False,False)) { + fprintf(stderr, "Can't load %s\n", servicesf); + } + + codepage_initialise(lp_client_code_page()); + load_interfaces(); + + /* Load command lists */ + + add_command_set(rpcclient_commands); + add_command_set(lsarpc_commands); + add_command_set(samr_commands); + add_command_set(spoolss_commands); + + /* Do anything specified with -c */ + + if (cmdstr[0]) { + pstring cmd; + char *p = cmdstr; + uint32 result; + + while(next_token(&p, cmd, ";", sizeof(pstring))) { + result = process_cmd(cmd); + } + + return 0; + } + + /* Loop around accepting commands */ + + while(1) { + pstring prompt, cmd; + uint32 result; + + slprintf(prompt, sizeof(prompt) - 1, "rpcclient> "); + +#if HAVE_READLINE + cmd = readline(prompt); +#else + printf("%s", prompt); + + if (!fgets(cmd, sizeof(cmd) - 1, stdin)) { + break; + } + + cmd[strlen(cmd) - 1] = '\0'; #endif - add_spl_commands(); + result = process_cmd(cmd); + } - return command_main(argc, argv); + return 0; } |