From 0184f3b6d8accd84cdb74da7dfd89df01e89c8b1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:37:42 +0000 Subject: checking for NULL really is counter-productive, and this one was also generating a warning (This used to be commit cd82ba41b8df024f034fcfa24e967ed8c3c8d035) --- source3/libsmb/cliconnect.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f0b02b97b0..472db69fd0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1119,11 +1119,6 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr ip; extern pstring global_myname; - if (!output_cli) { - DEBUG(0, ("output_cli is NULL!?!")); - SMB_ASSERT("output_cli for cli_full_connection was NULL.\n"); - } - if (!my_name) my_name = global_myname; -- cgit From 159118de5ce0999b96ebe7cd7dc823087b0cccf5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:54:35 +0000 Subject: fixed a number of real bugs found by warnings on the 64 bit irix compiler (This used to be commit 04de6bbc8055e5547af41b10e284b722f40e726d) --- source3/libsmb/cli_wkssvc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c index 756ff61e5b..97b948bf62 100644 --- a/source3/libsmb/cli_wkssvc.c +++ b/source3/libsmb/cli_wkssvc.c @@ -40,7 +40,6 @@ NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct rbuf; WKS_Q_QUERY_INFO q_o; WKS_R_QUERY_INFO r_o; - NTSTATUS nt_status; if (cli == NULL || wks100 == NULL) return NT_STATUS_UNSUCCESSFUL; @@ -89,6 +88,6 @@ NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* do clean up */ prs_mem_free(&rbuf); - return nt_status; + return NT_STATUS_OK; } -- cgit From 129b3966c04f4f1be33d35ca720e5946fbe76051 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Jul 2002 06:55:05 +0000 Subject: Add support for a weird behaviour apparently used by Win9X pass-through authentication - we can have an NT hash in the LM hash feild. (I need to double-check this fix with tpot, who discovered it). Also remove silly casts back and forth between uchar and char. Andrew Bartlett (This used to be commit 07e2b36311f91d7a20865a2ccc94716772e53fd7) --- source3/libsmb/smbencrypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 95434d0ae4..d15a83a515 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -226,14 +226,14 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ void SMBOWFencrypt_ntv2(const uchar kr[16], const DATA_BLOB srv_chal, const DATA_BLOB cli_chal, - char resp_buf[16]) + uchar resp_buf[16]) { HMACMD5Context ctx; hmac_md5_init_limK_to_64(kr, 16, &ctx); hmac_md5_update(srv_chal.data, srv_chal.length, &ctx); hmac_md5_update(cli_chal.data, cli_chal.length, &ctx); - hmac_md5_final((unsigned char *)resp_buf, &ctx); + hmac_md5_final(resp_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); -- cgit From badbae319a860c5590abeb7a947bacb47647c599 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Jul 2002 09:03:50 +0000 Subject: Fix up char/uchar casts etc. Fix up comments on some of the password hash wrappers. Andrew Bartlett (This used to be commit 95519d408caa7da00dbb2a8323cc4374a517cd69) --- source3/libsmb/cliconnect.c | 13 +++++-------- source3/libsmb/smbencrypt.c | 8 ++++---- 2 files changed, 9 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 472db69fd0..3cec5d743d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -54,9 +54,6 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, return False; } - /* Lanman2 cannot use SMB signing. */ - cli->sign_info.use_smb_signing = False; - /* if in share level security then don't send a password now */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { passlen = 0; @@ -269,10 +266,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* non encrypted password supplied. Ignore ntpass. */ passlen = 24; ntpasslen = 24; - SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); - SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); + SMBencrypt(pass,cli->secblob.data,(uchar *)pword); + SMBNTencrypt(pass,cli->secblob.data,(uchar *)ntpword); if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); + cli_calculate_mac_key(cli, pass, (uchar *)ntpword); tried_signing = True; } } else { @@ -482,8 +479,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, /* encrypt the password with the challenge */ memcpy(challenge, chal1.data + 24, 8); - SMBencrypt((unsigned char *)pass, challenge,lmhash); - SMBNTencrypt((unsigned char *)pass, challenge,nthash); + SMBencrypt(pass, challenge,lmhash); + SMBNTencrypt(pass, challenge,nthash); #if 0 file_save("nthash.dat", nthash, 24); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index d15a83a515..1ed83042d3 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -66,9 +66,9 @@ void E_md4hash(const char *passwd, uchar p16[16]) } /** - * Creates the MD4 Hash of the users password in NT UNICODE. + * Creates the DES forward-only Hash of the users password in DOS ASCII charset * @param passwd password in 'unix' charset. - * @param p16 return password hashed with md4, caller allocated 16 byte buffer + * @param p16 return password hashed with DES, caller allocated 16 byte buffer */ void E_deshash(const char *passwd, uchar p16[16]) @@ -77,7 +77,7 @@ void E_deshash(const char *passwd, uchar p16[16]) ZERO_STRUCT(dospwd); ZERO_STRUCTP(p16); - /* Password must be converted to DOS charset - null terminated. */ + /* Password must be converted to DOS charset - null terminated, uppercase. */ push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); E_P16(dospwd, p16); @@ -175,7 +175,7 @@ void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p /* Does the NT MD4 hash then des encryption. */ -void SMBNTencrypt(const uchar *passwd, uchar *c8, uchar *p24) +void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) { uchar p21[21]; -- cgit From ea9d3057e9cbd615176a7b98bcd935b6f9b434cb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Jul 2002 11:58:06 +0000 Subject: Try to fix up warnings - particularly on the IRIX 64 bit compiler (which had a distinction between uchar and char). Lots of const etc. Andrew Bartlett (This used to be commit 8196ee908e10db2119e480fe1b0a71b31a16febc) --- source3/libsmb/cli_srvsvc.c | 2 +- source3/libsmb/cliconnect.c | 28 ++++++++++++++++++++-------- source3/libsmb/namequery.c | 2 +- source3/libsmb/smbencrypt.c | 4 ++-- 4 files changed, 24 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 2dc12d726c..b92b356241 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -317,7 +317,7 @@ WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, } WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 file_level, char *user_name, + uint32 file_level, const char *user_name, SRV_FILE_INFO_CTR *ctr, int preferred_len, ENUM_HND *hnd) { diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3cec5d743d..1cf85875b6 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -254,11 +254,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); - fstring pword, ntpword; + uchar pword[24]; + uchar ntpword[24]; char *p; BOOL tried_signing = False; - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { + if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) { return False; } @@ -266,15 +267,21 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* non encrypted password supplied. Ignore ntpass. */ passlen = 24; ntpasslen = 24; - SMBencrypt(pass,cli->secblob.data,(uchar *)pword); - SMBNTencrypt(pass,cli->secblob.data,(uchar *)ntpword); + SMBencrypt(pass,cli->secblob.data,pword); + SMBNTencrypt(pass,cli->secblob.data,ntpword); if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, pass, (uchar *)ntpword); + cli_calculate_mac_key(cli, pass, ntpword); tried_signing = True; } } else { - memcpy(pword, pass, passlen); - memcpy(ntpword, ntpass, ntpasslen); + /* pre-encrypted password supplied. Only used for security=server, can't do + signing becouse we don't have oringial key */ + memcpy(pword, pass, 24); + if (ntpasslen == 24) { + memcpy(ntpword, ntpass, 24); + } else { + ZERO_STRUCT(ntpword); + } } /* send a session setup command */ @@ -302,8 +309,13 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, cli_setup_bcc(cli, p); cli_send_smb(cli); - if (!cli_receive_smb(cli)) + if (!cli_receive_smb(cli)) { + if (tried_signing) { + /* We only use it if we have a successful non-guest connect */ + cli->sign_info.use_smb_signing = False; + } return False; + } show_msg(cli->inbuf); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 18564bccf4..e2ddfd8280 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -930,7 +930,7 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) Find the IP address of the master browser or DMB for a workgroup. *********************************************************/ -BOOL find_master_ip(char *group, struct in_addr *master_ip) +BOOL find_master_ip(const char *group, struct in_addr *master_ip) { struct in_addr *ip_list = NULL; int count = 0; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 1ed83042d3..dfa355a7ec 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -28,7 +28,7 @@ This implements the X/Open SMB password encryption It takes a password ('unix' string), a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 */ -void SMBencrypt(const char *passwd, const uchar *c8, uchar *p24) +void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) { uchar p21[21]; @@ -337,7 +337,7 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, SMB signing - setup the MAC key. ************************************************************/ -void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, const uchar resp[24]) +void cli_calculate_mac_key(struct cli_state *cli, const char *ntpasswd, const uchar resp[24]) { /* Get first 16 bytes. */ E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]); -- cgit From 035738863609b0762a18962f1c471bb385254f10 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 21 Jul 2002 00:49:16 +0000 Subject: Renamed all the new_cli_netlogon_* functions to cli_netlogon_* as they're no longer new! (This used to be commit 277f6bbb9a63541a473a80a7994e9bde5c6f22dc) --- source3/libsmb/cli_netlogon.c | 30 +++++++++++++++--------------- source3/libsmb/trust_passwd.c | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index d32e0e77e4..acc9135542 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -28,8 +28,8 @@ /* LSA Request Challenge. Sends our challenge to server, then gets server response. These are used to generate the credentials. */ -NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, - DOM_CHAL *srv_chal) +NTSTATUS cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, + DOM_CHAL *srv_chal) { prs_struct qbuf, rbuf; NET_Q_REQ_CHAL q; @@ -42,7 +42,7 @@ NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, /* create and send a MSRPC command with api NET_REQCHAL */ - DEBUG(4,("new_cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", + DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", global_myname, cli->desthost, credstr(clnt_chal->data))); /* store the parameters */ @@ -84,9 +84,9 @@ Ensure that the server credential returned matches the session key encrypt of the server challenge originally received. JRA. ****************************************************************************/ -NTSTATUS new_cli_net_auth2(struct cli_state *cli, - uint16 sec_chan, - uint32 neg_flags, DOM_CHAL *srv_chal) +NTSTATUS cli_net_auth2(struct cli_state *cli, + uint16 sec_chan, + uint32 neg_flags, DOM_CHAL *srv_chal) { prs_struct qbuf, rbuf; NET_Q_AUTH_2 q; @@ -99,7 +99,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, /* create and send a MSRPC command with api NET_AUTH2 */ - DEBUG(4,("new_cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", + DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, credstr(cli->clnt_cred.challenge.data), neg_flags)); @@ -138,7 +138,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, /* * Server replied with bad credential. Fail. */ - DEBUG(0,("new_cli_net_auth2: server %s replied with bad credential (bad machine \ + DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \ password ?).\n", cli->desthost )); result = NT_STATUS_ACCESS_DENIED; goto done; @@ -154,9 +154,9 @@ password ?).\n", cli->desthost )); /* Initialize domain session credentials */ -NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, - uint16 sec_chan, - const unsigned char mach_pwd[16]) +NTSTATUS cli_nt_setup_creds(struct cli_state *cli, + uint16 sec_chan, + const unsigned char mach_pwd[16]) { DOM_CHAL clnt_chal; DOM_CHAL srv_chal; @@ -168,10 +168,10 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, generate_random_buffer(clnt_chal.data, 8, False); /* send a client challenge; receive a server challenge */ - result = new_cli_net_req_chal(cli, &clnt_chal, &srv_chal); + result = cli_net_req_chal(cli, &clnt_chal, &srv_chal); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("new_cli_nt_setup_creds: request challenge failed\n")); + DEBUG(0,("cli_nt_setup_creds: request challenge failed\n")); return result; } @@ -194,8 +194,8 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, * Receive an auth-2 challenge response and check it. */ - result = new_cli_net_auth2(cli, sec_chan, 0x000001ff, - &srv_chal); + result = cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); + if (!NT_STATUS_IS_OK(result)) { DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n", nt_errstr(result))); diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 3b77f7330e..fe6b673e39 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -35,7 +35,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ unsigned char new_trust_passwd_hash[16]) { NTSTATUS result; - result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { -- cgit From 88bef55a6efceef72a1378d0c7fa93c277fb1940 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 22 Jul 2002 14:00:40 +0000 Subject: fixed a segv in net time when the host is unavailable (This used to be commit f4f2b613a2a804a6d2e5e78cc7dd7f3482675fcd) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1cf85875b6..d304da7f51 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1071,7 +1071,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } if (cli->fd == -1) { DEBUG(1,("Error connecting to %s (%s)\n", - inet_ntoa(*ip),strerror(errno))); + ip?inet_ntoa(*ip):host,strerror(errno))); return False; } -- cgit From a56490007479b3f23f5159bfb7545136c40dd1fd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 26 Jul 2002 13:05:29 +0000 Subject: Mimir has been busy with patches again, and sent in the following patches: Andrew Bartlett From his e-mail: Below I attach the following patches as a result of my work on trusted domains support: 1) srv_samr_nt.c.diff This fixes a bug which caused to return null string as the first entry of enumerated accounts list (no matter what entry, it was always null string and rid) and possibly spoiled further names, depeding on their length. I found that while testing my 'net rpc trustdom list' against nt servers and samba server. 2) libsmb.diff Now, fallback to anonymous connection works correctly. 3) smbpasswd.c.diff Just a little fix which actually allows one to create a trusting domain account using smbpasswd 4) typos.diff As the name suggests, it's just a few typos fix :) (This used to be commit 888d595fab4f6b28318b743f47378cb7ca35d479) --- source3/libsmb/cliconnect.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d304da7f51..d29a6115fb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1191,9 +1191,8 @@ again: if (!cli_session_setup(cli, user, password, strlen(password)+1, password, strlen(password)+1, domain)) { - if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) - || cli_session_setup(cli, "", "", 0, - "", 0, domain)) { + if ((flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) + && cli_session_setup(cli, "", "", 0, "", 0, domain)) { } else { nt_status = cli_nt_error(cli); DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); -- cgit From 2a03547b6142ab934840332cda37013982cbe723 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Jul 2002 00:15:02 +0000 Subject: Rafal 'Mimir' Szczesniak has been busy again, and has added 'net rpc trustdom list' support. This lists the trusted and trusting domains of a remote PDC. I've applied these almost directly, just fixing some special case code for when there are *no* trusting domains. We still have some parse errors in this case however. Andrew Bartlett. From mimir's e-mail: Here are another patches adding trust relationship features. More details: Better error reporting in cli_lsa_enum_trust_dom(). Implementation of cli_samr_enum_dom_users() which cli_samr.c lacked. More "consts" -- one of arguments in net_find_dc(). Modified implementation of run_rpc_command() -- now it allows to reuse already opened connection (if it is passed) to remote server's IPC$ (e.g. as part of longer exchange of rpc calls). I'm sure Andrew will argue ;-) More neat version of rpc_trustdom_list() function. (This used to be commit f0890026820ee3e432147130b46de4610e583381) --- source3/libsmb/cli_lsarpc.c | 7 +-- source3/libsmb/cli_samr.c | 112 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 115 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 7dfee46fae..542fad311c 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -543,7 +543,7 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 *enum_ctx, uint32 *pref_num_domains, uint32 *num_domains, - char ***domain_names, DOM_SID **domain_sids) + char ***domain_names, DOM_SID **domain_sids) { prs_struct qbuf, rbuf; LSA_Q_ENUM_TRUST_DOM q; @@ -598,7 +598,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (!*domain_names) { DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_NO_MEMORY; goto done; } @@ -606,7 +606,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, r.num_domains); if (!domain_sids) { DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_NO_MEMORY; goto done; } @@ -632,6 +632,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + /** Enumerate privileges*/ NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 91577b3325..6581bdbeaf 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -5,7 +5,8 @@ Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000. + Copyright (C) Elrond 2000, + Copyright (C) Rafal Szczesniak 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 @@ -491,6 +492,115 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/** + * Enumerate domain users + * + * @param cli client state structure + * @param mem_ctx talloc context + * @param pol opened domain policy handle + * @param start_idx starting index of enumeration, returns context for + next enumeration + * @param acb_mask account control bit mask (to enumerate some particular + * kind of accounts) + * @param size max acceptable size of response + * @param dom_users returned array of domain user names + * @param rids returned array of domain user RIDs + * @param num_dom_users numer returned entries + * + * @return NTSTATUS returned in rpc response + **/ +NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask, + uint32 size, char ***dom_users, uint32 **rids, + uint32 *num_dom_users) +{ + prs_struct qdata; + prs_struct rdata; + SAMR_Q_ENUM_DOM_USERS q; + SAMR_R_ENUM_DOM_USERS r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + if (cli == NULL || pol == NULL) + return result; + + /* initialise parse structures */ + prs_init(&qdata, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rdata, 0, mem_ctx, UNMARSHALL); + + DEBUG(4, ("SAMR Enum Domain Users. start_idx: %d, acb: %d, size: %d\n", + *start_idx, acb_mask, size)); + + /* fill query structure with parameters */ + init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size); + + /* prepare query stream */ + if (!samr_io_q_enum_dom_users("", &q, &qdata, 0)) { + prs_mem_free(&qdata); + prs_mem_free(&rdata); + return result; + } + + /* send rpc call over the pipe */ + if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qdata, &rdata)) { + prs_mem_free(&qdata); + prs_mem_free(&rdata); + return result; + } + + /* unpack received stream */ + if(!samr_io_r_enum_dom_users("", &r, &rdata, 0)) { + prs_mem_free(&qdata); + prs_mem_free(&rdata); + result = r.status; + return result; + } + + /* return the data obtained in response */ + if (!NT_STATUS_IS_OK(r.status) && + (NT_STATUS_EQUAL(r.status, STATUS_MORE_ENTRIES) || + NT_STATUS_EQUAL(r.status, NT_STATUS_NO_MORE_ENTRIES))) { + return r.status; + } + + *start_idx = r.next_idx; + *num_dom_users = r.num_entries2; + result = r.status; + + if (r.num_entries2) { + /* allocate memory needed to return received data */ + *rids = (uint32*)talloc(mem_ctx, sizeof(uint32) * r.num_entries2); + if (!*rids) { + DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n")); + return NT_STATUS_NO_MEMORY; + } + + *dom_users = (char**)talloc(mem_ctx, sizeof(char*) * r.num_entries2); + if (!*dom_users) { + DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n")); + return NT_STATUS_NO_MEMORY; + } + + /* fill output buffers with rpc response */ + for (i = 0; i < r.num_entries2; i++) { + fstring conv_buf; + + (*rids)[i] = r.sam[i].rid; + unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1); + (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf); + } + } + + prs_mem_free(&qdata); + prs_mem_free(&rdata); + + return result; +}; + + /* Enumerate domain groups */ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, -- cgit From 3130577acb03a06fd8de27ee6c2e4f82bd4b2008 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 30 Jul 2002 04:32:29 +0000 Subject: Some crash fixes for netshareenum returning zero shares. (This used to be commit a5a0ff8bd7ee4a3586647d14fd750ec6df73efa8) --- source3/libsmb/cli_srvsvc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index b92b356241..1bdd19620b 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -116,6 +116,9 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, ZERO_STRUCTP(ctr); + if (!r.ctr.num_entries) + goto done; + ctr->info_level = info_level; ctr->num_entries = r.ctr.num_entries; -- cgit From 9edc1cd4cfd3c02cfb1b867f8450384c446e8b60 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 30 Jul 2002 15:03:14 +0000 Subject: this fixes plaintext passwords with win2000 there were 2 bugs: 1) we were sending a null challenge when we should have sent an empty challenge 2) the password can be in unicode if unicode is negotiated. This means our client code was wrong too :( (This used to be commit 1a6dfddf6788b30fc81794b1bfe749693183b2c1) --- source3/libsmb/cliconnect.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d29a6115fb..93cf3d95db 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -206,12 +206,11 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,cli->pid); SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,0); SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); - memcpy(p, pword, passlen); - p += passlen; + p += clistr_push(cli, p, pword, -1, STR_TERMINATE); /* password */ + SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); -- cgit From dcff12797e3e27abd378c9a7e7c0d036860a86ef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 31 Jul 2002 05:41:51 +0000 Subject: added 'disable netbios = yes/no' option, default is no When this option is disabled we should not do *any* netbios operations. You should also not start nmbd at all. I have put initial checks in at the major points we do netbios operations in smbd but there are bound to be more needed. Right now I've disabled all netbios name queries, all WINS lookups and node status queries in smbd and winbindd. I've been testing this option and the most noticable thing is how much more responsive things are! wthout those damn netbios timeouts things certainly are much slicker. (This used to be commit 12e7953bf2497eeb7c0bc6585d9fe58b3aabc240) --- source3/libsmb/namequery.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index e2ddfd8280..ae58c3a062 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -170,6 +170,11 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t int sock; BOOL result = False; + if (lp_disable_netbios()) { + DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type)); + return False; + } + DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, q_type, inet_ntoa(to_ip))); @@ -273,6 +278,11 @@ struct in_addr *name_query(int fd,const char *name,int name_type, struct nmb_packet *nmb = &p.packet.nmb; struct in_addr *ip_list = NULL; + if (lp_disable_netbios()) { + DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type)); + return NULL; + } + if (timed_out) { *timed_out = False; } @@ -556,6 +566,11 @@ BOOL name_resolve_bcast(const char *name, int name_type, int sock, i; int num_interfaces = iface_count(); + if (lp_disable_netbios()) { + DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type)); + return False; + } + *return_ip_list = NULL; *return_count = 0; @@ -602,6 +617,11 @@ BOOL resolve_wins(const char *name, int name_type, char **wins_tags; struct in_addr src_ip; + if (lp_disable_netbios()) { + DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type)); + return False; + } + *return_iplist = NULL; *return_count = 0; @@ -935,6 +955,11 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip) struct in_addr *ip_list = NULL; int count = 0; + if (lp_disable_netbios()) { + DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group)); + return False; + } + if (internal_resolve_name(group, 0x1D, &ip_list, &count)) { *master_ip = ip_list[0]; SAFE_FREE(ip_list); @@ -957,10 +982,14 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip) BOOL lookup_dc_name(const char *srcname, const char *domain, struct in_addr *dc_ip, char *ret_name) { -#if !defined(I_HATE_WINDOWS_REPLY_CODE) - +#if !defined(I_HATE_WINDOWS_REPLY_CODE) fstring dc_name; BOOL ret; + + if (lp_disable_netbios()) { + DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain)); + return False; + } /* * Due to the fact win WinNT *sucks* we must do a node status -- cgit From e9360f1a45d46a7def3e74c46d170eb843e1fb9e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 2 Aug 2002 07:20:56 +0000 Subject: Moved rpc client routines from libsmb back to rpc_client where they belong. (This used to be commit cb946b5dadf3cfd21bf584437c6a8e9425f6d5a7) --- source3/libsmb/cli_dfs.c | 245 ---- source3/libsmb/cli_lsarpc.c | 1169 ------------------- source3/libsmb/cli_netlogon.c | 664 ----------- source3/libsmb/cli_reg.c | 102 -- source3/libsmb/cli_samr.c | 1404 ----------------------- source3/libsmb/cli_spoolss.c | 2156 ----------------------------------- source3/libsmb/cli_spoolss_notify.c | 223 ---- source3/libsmb/cli_srvsvc.c | 445 -------- source3/libsmb/cli_wkssvc.c | 93 -- 9 files changed, 6501 deletions(-) delete mode 100644 source3/libsmb/cli_dfs.c delete mode 100644 source3/libsmb/cli_lsarpc.c delete mode 100644 source3/libsmb/cli_netlogon.c delete mode 100644 source3/libsmb/cli_reg.c delete mode 100644 source3/libsmb/cli_samr.c delete mode 100644 source3/libsmb/cli_spoolss.c delete mode 100644 source3/libsmb/cli_spoolss_notify.c delete mode 100644 source3/libsmb/cli_srvsvc.c delete mode 100644 source3/libsmb/cli_wkssvc.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c deleted file mode 100644 index 7fc27b9c3b..0000000000 --- a/source3/libsmb/cli_dfs.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - Copyright (C) Tim Potter 2000-2001, - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* Query DFS support */ - -NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL *dfs_exists) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_EXIST q; - DFS_R_DFS_EXIST r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_exist(&q); - - if (!dfs_io_q_dfs_exist("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_EXIST, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_exist("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - *dfs_exists = (r.status != 0); - - result = NT_STATUS_OK; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename, - char *comment, uint32 flags) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_ADD q; - DFS_R_DFS_ADD r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_add(&q, entrypath, servername, sharename, comment, - flags); - - if (!dfs_io_q_dfs_add("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_ADD, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_add("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_REMOVE q; - DFS_R_DFS_REMOVE r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_remove(&q, entrypath, servername, sharename); - - if (!dfs_io_q_dfs_remove("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_REMOVE, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_remove("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename, - uint32 info_level, DFS_INFO_CTR *ctr) - -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_GET_INFO q; - DFS_R_DFS_GET_INFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_get_info(&q, entrypath, servername, sharename, - info_level); - - if (!dfs_io_q_dfs_get_info("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_GET_INFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_get_info("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - *ctr = r.ctr; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enumerate dfs shares */ - -NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 info_level, DFS_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_ENUM q; - DFS_R_DFS_ENUM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_enum(&q, info_level, ctr); - - if (!dfs_io_q_dfs_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_ENUM, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!dfs_io_r_dfs_enum("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c deleted file mode 100644 index 542fad311c..0000000000 --- a/source3/libsmb/cli_lsarpc.c +++ /dev/null @@ -1,1169 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - Copyright (C) Tim Potter 2000-2001, - Copyright (C) Andrew Tridgell 1992-1997,2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, - Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000, - Copyright (C) Rafal Szczesniak 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** @defgroup lsa LSA - Local Security Architecture - * @ingroup rpc_client - * - * @{ - **/ - -/** - * @file cli_lsarpc.c - * - * RPC client routines for the LSA RPC pipe. LSA means "local - * security authority", which is half of a password database. - **/ - -/** Open a LSA policy handle - * - * @param cli Handle on an initialised SMB connection */ - -NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL sec_qos, uint32 des_access, POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPEN_POL q; - LSA_R_OPEN_POL r; - LSA_SEC_QOS qos; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - if (sec_qos) { - init_lsa_sec_qos(&qos, 2, 1, 0); - init_q_open_pol(&q, '\\', 0, des_access, &qos); - } else { - init_q_open_pol(&q, '\\', 0, des_access, NULL); - } - - /* Marshall data and send request */ - - if (!lsa_io_q_open_pol("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_open_pol("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *pol = r.pol; -#ifdef __INSURE__ - pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Open a LSA policy handle - * - * @param cli Handle on an initialised SMB connection - */ - -NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL sec_qos, uint32 des_access, POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPEN_POL2 q; - LSA_R_OPEN_POL2 r; - LSA_SEC_QOS qos; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - if (sec_qos) { - init_lsa_sec_qos(&qos, 2, 1, 0); - init_q_open_pol2(&q, cli->srv_name_slash, 0, des_access, - &qos); - } else { - init_q_open_pol2(&q, cli->srv_name_slash, 0, des_access, - NULL); - } - - /* Marshall data and send request */ - - if (!lsa_io_q_open_pol2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_OPENPOLICY2, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_open_pol2("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *pol = r.pol; -#ifdef __INSURE__ - pol->marker = (char *)malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Close a LSA policy handle */ - -NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_CLOSE q; - LSA_R_CLOSE r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_lsa_q_close(&q, pol); - - if (!lsa_io_q_close("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_CLOSE, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_close("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { -#ifdef __INSURE__ - SAFE_FREE(pol->marker); -#endif - *pol = r.pol; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Lookup a list of sids */ - -NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_sids, DOM_SID *sids, - char ***domains, char ***names, uint32 **types) -{ - prs_struct qbuf, rbuf; - LSA_Q_LOOKUP_SIDS q; - LSA_R_LOOKUP_SIDS r; - DOM_R_REF ref; - LSA_TRANS_NAME_ENUM t_names; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1); - - if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - ZERO_STRUCT(ref); - ZERO_STRUCT(t_names); - - r.dom_ref = &ref; - r.names = &t_names; - - if (!lsa_io_r_lookup_sids("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { - - /* An actual error occured */ - - goto done; - } - - /* Return output parameters */ - - if (r.mapped_count == 0) { - result = NT_STATUS_NONE_MAPPED; - goto done; - } - - if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * - num_sids))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * - num_sids))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * - num_sids))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < num_sids; i++) { - fstring name, dom_name; - uint32 dom_idx = t_names.name[i].domain_idx; - - /* Translate optimised name through domain index array */ - - if (dom_idx != 0xffffffff) { - - rpcstr_pull_unistr2_fstring( - dom_name, &ref.ref_dom[dom_idx].uni_dom_name); - rpcstr_pull_unistr2_fstring( - name, &t_names.uni_name[i]); - - (*names)[i] = talloc_strdup(mem_ctx, name); - (*domains)[i] = talloc_strdup(mem_ctx, dom_name); - (*types)[i] = t_names.name[i].sid_name_use; - - if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - } else { - (*names)[i] = NULL; - (*types)[i] = SID_NAME_UNKNOWN; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Lookup a list of names */ - -NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, - const char **names, DOM_SID **sids, - uint32 **types) -{ - prs_struct qbuf, rbuf; - LSA_Q_LOOKUP_NAMES q; - LSA_R_LOOKUP_NAMES r; - DOM_R_REF ref; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_lookup_names(mem_ctx, &q, pol, num_names, names); - - if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - ZERO_STRUCT(ref); - r.dom_ref = &ref; - - if (!lsa_io_r_lookup_names("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != - NT_STATUS_V(STATUS_SOME_UNMAPPED)) { - - /* An actual error occured */ - - goto done; - } - - /* Return output parameters */ - - if (r.mapped_count == 0) { - result = NT_STATUS_NONE_MAPPED; - goto done; - } - - if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * - num_names)))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * - num_names)))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < num_names; i++) { - DOM_RID2 *t_rids = r.dom_rid; - uint32 dom_idx = t_rids[i].rid_idx; - uint32 dom_rid = t_rids[i].rid; - DOM_SID *sid = &(*sids)[i]; - - /* Translate optimised sid through domain index array */ - - if (dom_idx != 0xffffffff) { - - sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid); - - if (dom_rid != 0xffffffff) { - sid_append_rid(sid, dom_rid); - } - - (*types)[i] = t_rids[i].type; - } else { - ZERO_STRUCTP(sid); - (*types)[i] = SID_NAME_UNKNOWN; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Query info policy - * - * @param domain_sid - returned remote server's domain sid */ - -NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint16 info_class, - fstring domain_name, DOM_SID *domain_sid) -{ - prs_struct qbuf, rbuf; - LSA_Q_QUERY_INFO q; - LSA_R_QUERY_INFO r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_query(&q, pol, info_class); - - if (!lsa_io_q_query("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_query("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - /* Return output parameters */ - - ZERO_STRUCTP(domain_sid); - domain_name[0] = '\0'; - - switch (info_class) { - - case 3: - if (r.dom.id3.buffer_dom_name != 0) { - unistr2_to_ascii(domain_name, - &r.dom.id3. - uni_domain_name, - sizeof (fstring) - 1); - } - - if (r.dom.id3.buffer_dom_sid != 0) { - *domain_sid = r.dom.id3.dom_sid.sid; - } - - break; - - case 5: - - if (r.dom.id5.buffer_dom_name != 0) { - unistr2_to_ascii(domain_name, &r.dom.id5. - uni_domain_name, - sizeof (fstring) - 1); - } - - if (r.dom.id5.buffer_dom_sid != 0) { - *domain_sid = r.dom.id5.dom_sid.sid; - } - - break; - - default: - DEBUG(3, ("unknown info class %d\n", info_class)); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** - * Enumerate list of trusted domains - * - * @param cli client state (cli_state) structure of the connection - * @param mem_ctx memory context - * @param pol opened lsa policy handle - * @param enum_ctx enumeration context ie. index of first returned domain entry - * @param pref_num_domains preferred max number of entries returned in one response - * @param num_domains total number of trusted domains returned by response - * @param domain_names returned trusted domain names - * @param domain_sids returned trusted domain sids - * - * @return nt status code of response - **/ - -NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_ctx, - uint32 *pref_num_domains, uint32 *num_domains, - char ***domain_names, DOM_SID **domain_sids) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_TRUST_DOM q; - LSA_R_ENUM_TRUST_DOM r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_enum_trust_dom(&q, pol, *enum_ctx, *pref_num_domains); - - if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_trust_dom("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) && - !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { - - /* An actual error ocured */ - - goto done; - } - - /* Return output parameters */ - - if (r.num_domains) { - - /* Allocate memory for trusted domain names and sids */ - - *domain_names = (char **)talloc(mem_ctx, sizeof(char *) * - r.num_domains); - - if (!*domain_names) { - DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_NO_MEMORY; - goto done; - } - - *domain_sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * - r.num_domains); - if (!domain_sids) { - DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_NO_MEMORY; - goto done; - } - - /* Copy across names and sids */ - - for (i = 0; i < r.num_domains; i++) { - fstring tmp; - - unistr2_to_ascii(tmp, &r.uni_domain_name[i], - sizeof(tmp) - 1); - (*domain_names)[i] = talloc_strdup(mem_ctx, tmp); - sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid); - } - } - - *num_domains = r.num_domains; - *enum_ctx = r.enum_context; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - - -/** Enumerate privileges*/ - -NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length, - uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_PRIVS q; - LSA_R_ENUM_PRIVS r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_enum_privs(&q, pol, *enum_context, pref_max_length); - - if (!lsa_io_q_enum_privs("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUM_PRIVS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_privs("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - /* Return output parameters */ - - *enum_context = r.enum_context; - *count = r.count; - - if (!((*privs_name = (char **)talloc(mem_ctx, sizeof(char *) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*privs_high = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*privs_low = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < r.count; i++) { - fstring name; - - rpcstr_pull_unistr2_fstring( name, &r.privs[i].name); - - (*privs_name)[i] = talloc_strdup(mem_ctx, name); - - (*privs_high)[i] = r.privs[i].luid_high; - (*privs_low)[i] = r.privs[i].luid_low; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Get privilege name */ - -NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, char *name, uint16 lang_id, uint16 lang_id_sys, - fstring description, uint16 *lang_id_desc) -{ - prs_struct qbuf, rbuf; - LSA_Q_PRIV_GET_DISPNAME q; - LSA_R_PRIV_GET_DISPNAME r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys); - - if (!lsa_io_q_priv_get_dispname("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_PRIV_GET_DISPNAME, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_priv_get_dispname("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - /* Return output parameters */ - - rpcstr_pull_unistr2_fstring(description , &r.desc); - *lang_id_desc = r.lang_id; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Enumerate list of SIDs */ - -NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length, - uint32 *num_sids, DOM_SID **sids) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_ACCOUNTS q; - LSA_R_ENUM_ACCOUNTS r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length); - - if (!lsa_io_q_enum_accounts("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUM_ACCOUNTS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_accounts("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.sids.num_entries==0) - goto done; - - /* Return output parameters */ - - *sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.sids.num_entries); - if (!*sids) { - DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Copy across names and sids */ - - for (i = 0; i < r.sids.num_entries; i++) { - sid_copy(&(*sids)[i], &r.sids.sid[i].sid); - } - - *num_sids= r.sids.num_entries; - *enum_ctx = r.enum_context; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Open a LSA user handle - * - * @param cli Handle on an initialised SMB connection */ - -NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access, - POLICY_HND *user_pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPENACCOUNT q; - LSA_R_OPENACCOUNT r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_lsa_q_open_account(&q, dom_pol, sid, des_access); - - /* Marshall data and send request */ - - if (!lsa_io_q_open_account("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_OPENACCOUNT, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_open_account("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *user_pol = r.pol; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Enumerate user privileges - * - * @param cli Handle on an initialised SMB connection */ - -NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *count, LUID_ATTR **set) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUMPRIVSACCOUNT q; - LSA_R_ENUMPRIVSACCOUNT r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_lsa_q_enum_privsaccount(&q, pol); - - /* Marshall data and send request */ - - if (!lsa_io_q_enum_privsaccount("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUMPRIVSACCOUNT, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_privsaccount("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.count == 0) - goto done; - - if (!((*set = (LUID_ATTR *)talloc(mem_ctx, sizeof(LUID_ATTR) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i=0; imem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); - - /* create and send a MSRPC command with api NET_REQCHAL */ - - DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", - global_myname, cli->desthost, credstr(clnt_chal->data))); - - /* store the parameters */ - init_q_req_chal(&q, cli->srv_name_slash, global_myname, clnt_chal); - - /* Marshall data and send request */ - - if (!net_io_q_req_chal("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_REQCHAL, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarhall response */ - - if (!net_io_r_req_chal("", &r, &rbuf, 0)) { - goto done; - } - - result = r.status; - - /* Return result */ - - if (NT_STATUS_IS_OK(result)) { - memcpy(srv_chal, r.srv_chal.data, sizeof(srv_chal->data)); - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/**************************************************************************** -LSA Authenticate 2 - -Send the client credential, receive back a server credential. -Ensure that the server credential returned matches the session key -encrypt of the server challenge originally received. JRA. -****************************************************************************/ - -NTSTATUS cli_net_auth2(struct cli_state *cli, - uint16 sec_chan, - uint32 neg_flags, DOM_CHAL *srv_chal) -{ - prs_struct qbuf, rbuf; - NET_Q_AUTH_2 q; - NET_R_AUTH_2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - extern pstring global_myname; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); - - /* create and send a MSRPC command with api NET_AUTH2 */ - - DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", - cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, - credstr(cli->clnt_cred.challenge.data), neg_flags)); - - /* store the parameters */ - init_q_auth_2(&q, cli->srv_name_slash, cli->mach_acct, - sec_chan, global_myname, &cli->clnt_cred.challenge, - neg_flags); - - /* turn parameters into data stream */ - - if (!net_io_q_auth_2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_AUTH2, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_auth_2("", &r, &rbuf, 0)) { - goto done; - } - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - UTIME zerotime; - - /* - * Check the returned value using the initial - * server received challenge. - */ - - zerotime.time = 0; - if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, - zerotime) == 0) { - - /* - * Server replied with bad credential. Fail. - */ - DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \ -password ?).\n", cli->desthost )); - result = NT_STATUS_ACCESS_DENIED; - goto done; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Initialize domain session credentials */ - -NTSTATUS cli_nt_setup_creds(struct cli_state *cli, - uint16 sec_chan, - const unsigned char mach_pwd[16]) -{ - DOM_CHAL clnt_chal; - DOM_CHAL srv_chal; - UTIME zerotime; - NTSTATUS result; - - /******************* Request Challenge ********************/ - - generate_random_buffer(clnt_chal.data, 8, False); - - /* send a client challenge; receive a server challenge */ - result = cli_net_req_chal(cli, &clnt_chal, &srv_chal); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("cli_nt_setup_creds: request challenge failed\n")); - return result; - } - - /**************** Long-term Session key **************/ - - /* calculate the session key */ - cred_session_key(&clnt_chal, &srv_chal, mach_pwd, - cli->sess_key); - memset((char *)cli->sess_key+8, '\0', 8); - - /******************* Authenticate 2 ********************/ - - /* calculate auth-2 credentials */ - zerotime.time = 0; - cred_create(cli->sess_key, &clnt_chal, zerotime, - &cli->clnt_cred.challenge); - - /* - * Send client auth-2 challenge. - * Receive an auth-2 challenge response and check it. - */ - - result = cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n", - nt_errstr(result))); - } - - return result; -} - -/* Logon Control 2 */ - -NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 query_level) -{ - prs_struct qbuf, rbuf; - NET_Q_LOGON_CTRL2 q; - NET_R_LOGON_CTRL2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_net_q_logon_ctrl2(&q, cli->srv_name_slash, query_level); - - /* Marshall data and send request */ - - if (!net_io_q_logon_ctrl2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_logon_ctrl2("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/**************************************************************************** -Generate the next creds to use. Yuck - this is a cut&paste from another -file. They should be combined at some stage. )-: -****************************************************************************/ - -static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) -{ - /* - * Create the new client credentials. - */ - - cli->clnt_cred.timestamp.time = time(NULL); - - memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred)); - - /* Calculate the new credentials. */ - cred_create(cli->sess_key, &(cli->clnt_cred.challenge), - new_clnt_cred->timestamp, &(new_clnt_cred->challenge)); - -} - -/* Sam synchronisation */ - -NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED *ret_creds, - uint32 database_id, uint32 *num_deltas, - SAM_DELTA_HDR **hdr_deltas, - SAM_DELTA_CTR **deltas) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_SYNC q; - NET_R_SAM_SYNC r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2, - &clnt_creds, ret_creds, database_id); - - /* Marshall data and send request */ - - if (!net_io_q_sam_sync("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAM_SYNC, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_sam_sync("", cli->sess_key, &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return results */ - - result = r.status; - *num_deltas = r.num_deltas2; - *hdr_deltas = r.hdr_deltas; - *deltas = r.deltas; - - memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds)); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Sam synchronisation */ - -NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 database_id, UINT64_S seqnum, - uint32 *num_deltas, - SAM_DELTA_HDR **hdr_deltas, - SAM_DELTA_CTR **deltas) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_DELTAS q; - NET_R_SAM_DELTAS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - init_net_q_sam_deltas(&q, cli->srv_name_slash, - cli->clnt_name_slash + 2, &clnt_creds, - database_id, seqnum); - - /* Marshall data and send request */ - - if (!net_io_q_sam_deltas("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAM_DELTAS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_sam_deltas("", cli->sess_key, &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return results */ - - result = r.status; - *num_deltas = r.num_deltas2; - *hdr_deltas = r.hdr_deltas; - *deltas = r.deltas; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Logon domain user */ - -NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *username, char *password, - int logon_type) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds, dummy_rtn_creds; - extern pstring global_myname; - NET_ID_INFO_CTR ctr; - NET_USER_INFO_3 user; - int validation_level = 3; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - q.validation_level = validation_level; - - memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); - dummy_rtn_creds.timestamp.time = time(NULL); - - ctr.switch_value = logon_type; - - switch (logon_type) { - case INTERACTIVE_LOGON_TYPE: { - unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16]; - - nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); - - init_id_info1(&ctr.auth.id1, lp_workgroup(), - 0, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, cli->clnt_name_slash, - cli->sess_key, lm_owf_user_pwd, - nt_owf_user_pwd); - - break; - } - case NET_LOGON_TYPE: { - uint8 chal[8]; - unsigned char local_lm_response[24]; - unsigned char local_nt_response[24]; - - generate_random_buffer(chal, 8, False); - - SMBencrypt(password, chal, local_lm_response); - SMBNTencrypt(password, chal, local_nt_response); - - init_id_info2(&ctr.auth.id2, lp_workgroup(), - 0, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, cli->clnt_name_slash, chal, - local_lm_response, 24, local_nt_response, 24); - break; - } - default: - DEBUG(0, ("switch value %d not supported\n", - ctr.switch_value)); - goto done; - } - - init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, - &clnt_creds, &dummy_rtn_creds, logon_type, - &ctr); - - /* Marshall data and send request */ - - if (!net_io_q_sam_logon("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.user = &user; - - if (!net_io_r_sam_logon("", &r, &rbuf, 0)) { - goto done; - } - - /* Return results */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - - -/** - * Logon domain user with an 'network' SAM logon - * - * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller. - **/ - -NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, - const char *username, const char *domain, const char *workstation, - const uint8 chal[8], - DATA_BLOB lm_response, DATA_BLOB nt_response, - NET_USER_INFO_3 *info3) - -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds, dummy_rtn_creds; - NET_ID_INFO_CTR ctr; - extern pstring global_myname; - int validation_level = 3; - char *workstation_name_slash; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation); - - if (!workstation_name_slash) { - DEBUG(0, ("talloc_asprintf failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - q.validation_level = validation_level; - - memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); - dummy_rtn_creds.timestamp.time = time(NULL); - - ctr.switch_value = NET_LOGON_TYPE; - - init_id_info2(&ctr.auth.id2, domain, - 0, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, workstation_name_slash, (const uchar*)chal, - lm_response.data, lm_response.length, nt_response.data, nt_response.length); - - init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, - &clnt_creds, &dummy_rtn_creds, NET_LOGON_TYPE, - &ctr); - - /* Marshall data and send request */ - - if (!net_io_q_sam_logon("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.user = info3; - - if (!net_io_r_sam_logon("", &r, &rbuf, 0)) { - goto done; - } - - /* Return results */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/*************************************************************************** -LSA Server Password Set. -****************************************************************************/ - -NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char* machine_name, uint8 hashed_mach_pwd[16]) -{ - prs_struct rbuf; - prs_struct qbuf; - DOM_CRED new_clnt_cred; - NET_Q_SRV_PWSET q_s; - uint16 sec_chan_type = 2; - NTSTATUS nt_status; - char *mach_acct; - - gen_next_creds( cli, &new_clnt_cred); - - prs_init(&qbuf , 1024, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* create and send a MSRPC command with api NET_SRV_PWSET */ - - mach_acct = talloc_asprintf(mem_ctx, "%s$", machine_name); - - if (!mach_acct) { - DEBUG(0,("talloc_asprintf failed!\n")); - nt_status = NT_STATUS_NO_MEMORY; - goto done; - } - - DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n", - cli->srv_name_slash, mach_acct, sec_chan_type, machine_name, - credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time)); - - /* store the parameters */ - init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->sess_key, - mach_acct, sec_chan_type, machine_name, - &new_clnt_cred, (char *)hashed_mach_pwd); - - /* turn parameters into data stream */ - if(!net_io_q_srv_pwset("", &q_s, &qbuf, 0)) { - DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n")); - nt_status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, NET_SRVPWSET, &qbuf, &rbuf)) - { - NET_R_SRV_PWSET r_s; - - if (!net_io_r_srv_pwset("", &r_s, &rbuf, 0)) { - nt_status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - nt_status = r_s.status; - - if (!NT_STATUS_IS_OK(r_s.status)) - { - /* report error code */ - DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(nt_status))); - goto done; - } - - /* Update the credentials. */ - if (!clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred))) - { - /* - * Server replied with bad credential. Fail. - */ - DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \ -password ?).\n", cli->desthost )); - nt_status = NT_STATUS_UNSUCCESSFUL; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return nt_status; -} - diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c deleted file mode 100644 index aaf18882f7..0000000000 --- a/source3/libsmb/cli_reg.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC Pipe client - - Copyright (C) Andrew Tridgell 1992-1998, - Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - Copyright (C) Paul Ashton 1997-1998. - Copyright (C) Jeremy Allison 1999. - Copyright (C) Simo Sorce 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* Shutdown a server */ - -NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, - const char *msg, uint32 timeout, uint16 flags) -{ - prs_struct qbuf; - prs_struct rbuf; - REG_Q_SHUTDOWN q_s; - REG_R_SHUTDOWN r_s; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - if (msg == NULL) return NT_STATUS_INVALID_PARAMETER; - - ZERO_STRUCT (q_s); - ZERO_STRUCT (r_s); - - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_shutdown(&q_s, msg, timeout, flags); - - if (!reg_io_q_shutdown("", &q_s, &qbuf, 0) || - !rpc_api_pipe_req(cli, REG_SHUTDOWN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if(reg_io_r_shutdown("", &r_s, &rbuf, 0)) - result = r_s.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; -} - - -/* Abort a server shutdown */ - -NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx) -{ - prs_struct rbuf; - prs_struct qbuf; - REG_Q_ABORT_SHUTDOWN q_s; - REG_R_ABORT_SHUTDOWN r_s; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT (q_s); - ZERO_STRUCT (r_s); - - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_abort_shutdown(&q_s); - - if (!reg_io_q_abort_shutdown("", &q_s, &qbuf, 0) || - !rpc_api_pipe_req(cli, REG_ABORT_SHUTDOWN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (reg_io_r_abort_shutdown("", &r_s, &rbuf, 0)) - result = r_s.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf ); - - return result; -} diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c deleted file mode 100644 index 6581bdbeaf..0000000000 --- a/source3/libsmb/cli_samr.c +++ /dev/null @@ -1,1404 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - Copyright (C) Tim Potter 2000-2001, - Copyright (C) Andrew Tridgell 1992-1997,2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, - Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000, - Copyright (C) Rafal Szczesniak 2002. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* Connect to SAMR database */ - -NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 access_mask, POLICY_HND *connect_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_CONNECT q; - SAMR_R_CONNECT r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_connect(&q, cli->desthost, access_mask); - - if (!samr_io_q_connect("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_connect("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *connect_pol = r.connect_pol; -#ifdef __INSURE__ - connect_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Close SAMR handle */ - -NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_CLOSE_HND q; - SAMR_R_CLOSE_HND r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_close_hnd(&q, connect_pol); - - if (!samr_io_q_close_hnd("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { -#ifdef __INSURE__ - SAFE_FREE(connect_pol->marker); -#endif - *connect_pol = r.pol; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on a domain */ - -NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol, uint32 access_mask, - const DOM_SID *domain_sid, POLICY_HND *domain_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_DOMAIN q; - SAMR_R_OPEN_DOMAIN r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid); - - if (!samr_io_q_open_domain("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_open_domain("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *domain_pol = r.domain_pol; -#ifdef __INSURE__ - domain_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on a user */ - -NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 user_rid, POLICY_HND *user_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_USER q; - SAMR_R_OPEN_USER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_user(&q, domain_pol, access_mask, user_rid); - - if (!samr_io_q_open_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_open_user("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *user_pol = r.user_pol; -#ifdef __INSURE__ - user_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on a group */ - -NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 group_rid, POLICY_HND *group_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_GROUP q; - SAMR_R_OPEN_GROUP r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_group(&q, domain_pol, access_mask, group_rid); - - if (!samr_io_q_open_group("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_open_group("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *group_pol = r.pol; -#ifdef __INSURE__ - group_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user info */ - -NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - SAM_USERINFO_CTR **ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_USERINFO q; - SAMR_R_QUERY_USERINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_userinfo(&q, user_pol, switch_value); - - if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - *ctr = r.ctr; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query group info */ - -NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, uint32 info_level, - GROUP_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_GROUPINFO q; - SAMR_R_QUERY_GROUPINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_groupinfo(&q, group_pol, info_level); - - if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user groups */ - -NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint32 *num_groups, - DOM_GID **gid) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_USERGROUPS q; - SAMR_R_QUERY_USERGROUPS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_usergroups(&q, user_pol); - - if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *num_groups = r.num_entries; - *gid = r.gid; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user aliases */ - -NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid, - uint32 *num_aliases, uint32 **als_rids) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_USERALIASES q; - SAMR_R_QUERY_USERALIASES r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - unsigned int ptr=1; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid); - - if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *num_aliases = r.num_entries; - *als_rids = r.rid; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user groups */ - -NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, uint32 *num_mem, - uint32 **rid, uint32 **attr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_GROUPMEM q; - SAMR_R_QUERY_GROUPMEM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_groupmem(&q, group_pol); - - if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *num_mem = r.num_entries; - *rid = r.rid; - *attr = r.attr; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** - * Enumerate domain users - * - * @param cli client state structure - * @param mem_ctx talloc context - * @param pol opened domain policy handle - * @param start_idx starting index of enumeration, returns context for - next enumeration - * @param acb_mask account control bit mask (to enumerate some particular - * kind of accounts) - * @param size max acceptable size of response - * @param dom_users returned array of domain user names - * @param rids returned array of domain user RIDs - * @param num_dom_users numer returned entries - * - * @return NTSTATUS returned in rpc response - **/ -NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask, - uint32 size, char ***dom_users, uint32 **rids, - uint32 *num_dom_users) -{ - prs_struct qdata; - prs_struct rdata; - SAMR_Q_ENUM_DOM_USERS q; - SAMR_R_ENUM_DOM_USERS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - if (cli == NULL || pol == NULL) - return result; - - /* initialise parse structures */ - prs_init(&qdata, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rdata, 0, mem_ctx, UNMARSHALL); - - DEBUG(4, ("SAMR Enum Domain Users. start_idx: %d, acb: %d, size: %d\n", - *start_idx, acb_mask, size)); - - /* fill query structure with parameters */ - init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size); - - /* prepare query stream */ - if (!samr_io_q_enum_dom_users("", &q, &qdata, 0)) { - prs_mem_free(&qdata); - prs_mem_free(&rdata); - return result; - } - - /* send rpc call over the pipe */ - if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qdata, &rdata)) { - prs_mem_free(&qdata); - prs_mem_free(&rdata); - return result; - } - - /* unpack received stream */ - if(!samr_io_r_enum_dom_users("", &r, &rdata, 0)) { - prs_mem_free(&qdata); - prs_mem_free(&rdata); - result = r.status; - return result; - } - - /* return the data obtained in response */ - if (!NT_STATUS_IS_OK(r.status) && - (NT_STATUS_EQUAL(r.status, STATUS_MORE_ENTRIES) || - NT_STATUS_EQUAL(r.status, NT_STATUS_NO_MORE_ENTRIES))) { - return r.status; - } - - *start_idx = r.next_idx; - *num_dom_users = r.num_entries2; - result = r.status; - - if (r.num_entries2) { - /* allocate memory needed to return received data */ - *rids = (uint32*)talloc(mem_ctx, sizeof(uint32) * r.num_entries2); - if (!*rids) { - DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - *dom_users = (char**)talloc(mem_ctx, sizeof(char*) * r.num_entries2); - if (!*dom_users) { - DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - /* fill output buffers with rpc response */ - for (i = 0; i < r.num_entries2; i++) { - fstring conv_buf; - - (*rids)[i] = r.sam[i].rid; - unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1); - (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf); - } - } - - prs_mem_free(&qdata); - prs_mem_free(&rdata); - - return result; -}; - - -/* Enumerate domain groups */ - -NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *start_idx, - uint32 size, struct acct_info **dom_groups, - uint32 *num_dom_groups) -{ - prs_struct qbuf, rbuf; - SAMR_Q_ENUM_DOM_GROUPS q; - SAMR_R_ENUM_DOM_GROUPS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 name_idx, i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_enum_dom_groups(&q, pol, *start_idx, size); - - if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) - goto done; - - *num_dom_groups = r.num_entries2; - - if (!((*dom_groups) = (struct acct_info *) - talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups); - - name_idx = 0; - - for (i = 0; i < *num_dom_groups; i++) { - - (*dom_groups)[i].rid = r.sam[i].rid; - - if (r.sam[i].hdr_name.buffer) { - unistr2_to_ascii((*dom_groups)[i].acct_name, - &r.uni_grp_name[name_idx], - sizeof(fstring) - 1); - name_idx++; - } - - *start_idx = r.next_idx; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enumerate domain groups */ - -NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *start_idx, - uint32 size, struct acct_info **dom_groups, - uint32 *num_dom_groups) -{ - prs_struct qbuf, rbuf; - SAMR_Q_ENUM_DOM_ALIASES q; - SAMR_R_ENUM_DOM_ALIASES r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 name_idx, i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size); - - if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { - goto done; - } - - *num_dom_groups = r.num_entries2; - - if (!((*dom_groups) = (struct acct_info *) - talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups); - - name_idx = 0; - - for (i = 0; i < *num_dom_groups; i++) { - - (*dom_groups)[i].rid = r.sam[i].rid; - - if (r.sam[i].hdr_name.buffer) { - unistr2_to_ascii((*dom_groups)[i].acct_name, - &r.uni_grp_name[name_idx], - sizeof(fstring) - 1); - name_idx++; - } - - *start_idx = r.next_idx; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query alias members */ - -NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *alias_pol, uint32 *num_mem, - DOM_SID **sids) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_ALIASMEM q; - SAMR_R_QUERY_ALIASMEM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_aliasmem(&q, alias_pol); - - if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - *num_mem = r.num_sids; - - if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < *num_mem; i++) { - (*sids)[i] = r.sid[i].sid; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on an alias */ - -NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 alias_rid, POLICY_HND *alias_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_ALIAS q; - SAMR_R_OPEN_ALIAS r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid); - - if (!samr_io_q_open_alias("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_open_alias("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *alias_pol = r.pol; -#ifdef __INSURE__ - alias_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query domain info */ - -NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint16 switch_value, - SAM_UNK_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_DOMAIN_INFO q; - SAMR_R_QUERY_DOMAIN_INFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_dom_info(&q, domain_pol, switch_value); - - if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query display info */ - -NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 *start_idx, - uint16 switch_value, uint32 *num_entries, - uint32 max_entries, SAM_DISPINFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_DISPINFO q; - SAMR_R_QUERY_DISPINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_dispinfo(&q, domain_pol, switch_value, - *start_idx, max_entries); - - if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { - goto done; - } - - *num_entries = r.num_entries; - *start_idx += r.num_entries; /* No next_idx in this structure! */ - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are - looked up in one packet. */ - -NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 flags, - uint32 num_rids, uint32 *rids, - uint32 *num_names, char ***names, - uint32 **name_types) -{ - prs_struct qbuf, rbuf; - SAMR_Q_LOOKUP_RIDS q; - SAMR_R_LOOKUP_RIDS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 i; - - if (num_rids > 1000) { - DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if " - "more than ~1000 rids are looked up at once.\n")); - } - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags, - num_rids, rids); - - if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.num_names1 == 0) { - *num_names = 0; - *names = NULL; - goto done; - } - - *num_names = r.num_names1; - *names = talloc(mem_ctx, sizeof(char *) * r.num_names1); - *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1); - - for (i = 0; i < r.num_names1; i++) { - fstring tmp; - - unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1); - (*names)[i] = talloc_strdup(mem_ctx, tmp); - (*name_types)[i] = r.type[i]; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Lookup names */ - -NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 flags, - uint32 num_names, const char **names, - uint32 *num_rids, uint32 **rids, - uint32 **rid_types) -{ - prs_struct qbuf, rbuf; - SAMR_Q_LOOKUP_NAMES q; - SAMR_R_LOOKUP_NAMES r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags, - num_names, names); - - if (!samr_io_q_lookup_names("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.num_rids1 == 0) { - *num_rids = 0; - goto done; - } - - *num_rids = r.num_rids1; - *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1); - *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1); - - for (i = 0; i < r.num_rids1; i++) { - (*rids)[i] = r.rids[i]; - (*rid_types)[i] = r.types[i]; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Create a domain user */ - -NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, const char *acct_name, - uint32 acb_info, uint32 unknown, - POLICY_HND *user_pol, uint32 *rid) -{ - prs_struct qbuf, rbuf; - SAMR_Q_CREATE_USER q; - SAMR_R_CREATE_USER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown); - - if (!samr_io_q_create_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_create_user("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (user_pol) - *user_pol = r.user_pol; - - if (rid) - *rid = r.user_rid; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set userinfo */ - -NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - uchar sess_key[16], SAM_USERINFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_SET_USERINFO q; - SAMR_R_SET_USERINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - q.ctr = ctr; - - init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, - ctr->info.id); - - if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set userinfo2 */ - -NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - uchar sess_key[16], SAM_USERINFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_SET_USERINFO2 q; - SAMR_R_SET_USERINFO2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr); - - if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Delete domain user */ - -NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_DELETE_DOM_USER q; - SAMR_R_DELETE_DOM_USER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_delete_dom_user(&q, user_pol); - - if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user security object */ - -NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_SEC_OBJ q; - SAMR_R_QUERY_SEC_OBJ r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_sec_obj(&q, user_pol, switch_value); - - if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Get domain password info */ - -NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint16 *unk_0, uint16 *unk_1, uint16 *unk_2) -{ - prs_struct qbuf, rbuf; - SAMR_Q_GET_DOM_PWINFO q; - SAMR_R_GET_DOM_PWINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_get_dom_pwinfo(&q, cli->desthost); - - if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - if (unk_0) - *unk_0 = r.unk_0; - if (unk_1) - *unk_1 = r.unk_1; - if (unk_2) - *unk_2 = r.unk_2; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c deleted file mode 100644 index 18e17758d6..0000000000 --- a/source3/libsmb/cli_spoolss.c +++ /dev/null @@ -1,2156 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - - Copyright (C) Gerald Carter 2001-2002, - Copyright (C) Tim Potter 2000-2002, - Copyright (C) Andrew Tridgell 1994-2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Jean-Francois Micouleau 1999-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 - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** @defgroup spoolss SPOOLSS - NT printing routines - * @ingroup rpc_client - * - * @{ - **/ - -/********************************************************************** - Initialize a new spoolss buff for use by a client rpc -**********************************************************************/ -static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) -{ - buffer->ptr = (size != 0); - buffer->size = size; - buffer->string_at_end = size; - prs_init(&buffer->prs, size, ctx, MARSHALL); - buffer->struct_start = prs_offset(&buffer->prs); -} - -/********************************************************************* - Decode various spoolss rpc's and info levels - ********************************************************************/ - -/********************************************************************** -**********************************************************************/ -static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 returned, PRINTER_INFO_0 **info) -{ - uint32 i; - PRINTER_INFO_0 *inf; - - inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0)); - - buffer->prs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs, 0); - - for (i=0; iprs, 0); - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs, 0); - - smb_io_driverdir_1("", buffer, inf, 0); - - *info=inf; -} - -/** Return a handle to the specified printer or print server. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param printername The name of the printer or print server to be - * opened in UNC format. - * - * @param datatype Specifies the default data type for the printer. - * - * @param access_required The access rights requested on the printer or - * print server. - * - * @param station The UNC name of the requesting workstation. - * - * @param username The name of the user requesting the open. - * - * @param pol Returned policy handle. - */ - -/********************************************************************************* - Win32 API - OpenPrinter() - ********************************************************************************/ - -WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *printername, char *datatype, uint32 access_required, - char *station, char *username, POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_OPEN_PRINTER_EX q; - SPOOL_R_OPEN_PRINTER_EX r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_open_printer_ex(&q, printername, datatype, - access_required, station, username); - - /* Marshall data and send request */ - - if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *pol = r.handle; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Close a printer handle - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param pol Policy handle of printer or print server to close. - */ -/********************************************************************************* - Win32 API - ClosePrinter() - ********************************************************************************/ - -WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_CLOSEPRINTER q; - SPOOL_R_CLOSEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_closeprinter(&q, pol); - - /* Marshall data and send request */ - - if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *pol = r.handle; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Enumerate printers on a print server. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * may be NULL. - * - * @param flags Selected from PRINTER_ENUM_* flags. - * @param level Request information level. - * - * @param num_printers Pointer to number of printers returned. May be - * NULL. - * @param ctr Return structure for printer information. May - * be NULL. - */ -/********************************************************************************* - Win32 API - EnumPrinters() - ********************************************************************************/ - -WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 flags, uint32 level, - uint32 *num_printers, PRINTER_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERS q; - SPOOL_R_ENUMPRINTERS r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - result = r.status; - - /* Return output parameters */ - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - if (num_printers) - *num_printers = r.returned; - - if (!ctr) - goto done; - - switch (level) { - case 0: - decode_printer_info_0(mem_ctx, r.buffer, r.returned, - &ctr->printers_0); - break; - case 1: - decode_printer_info_1(mem_ctx, r.buffer, r.returned, - &ctr->printers_1); - break; - case 2: - decode_printer_info_2(mem_ctx, r.buffer, r.returned, - &ctr->printers_2); - break; - case 3: - decode_printer_info_3(mem_ctx, r.buffer, r.returned, - &ctr->printers_3); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - EnumPorts() - ********************************************************************************/ -/** Enumerate printer ports on a print server. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * May be NULL. - * - * @param level Requested information level. - * - * @param num_ports Pointer to number of ports returned. May be NULL. - * @param ctr Pointer to structure holding port information. - * May be NULL. - */ - -WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 level, int *num_ports, PORT_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPORTS q; - SPOOL_R_ENUMPORTS r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_enumports(&q, server, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumports("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_enumports("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - result = r.status; - - /* Return output parameters */ - - if (!W_ERROR_IS_OK(result)) - goto done; - - if (num_ports) - *num_ports = r.returned; - - if (!ctr) - goto done; - - switch (level) { - case 1: - decode_port_info_1(mem_ctx, r.buffer, r.returned, - &ctr->port.info_1); - break; - case 2: - decode_port_info_2(mem_ctx, r.buffer, r.returned, - &ctr->port.info_2); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - GetPrinter() - ********************************************************************************/ - -WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTER q; - SPOOL_R_GETPRINTER r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getprinter("", &r, &rbuf, 0)) - goto done; - - if (needed) - *needed = r.needed; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) { - switch (level) { - case 0: - decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); - break; - case 1: - decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1); - break; - case 2: - decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2); - break; - case 3: - decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3); - break; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - SetPrinter() - ********************************************************************************/ -/** Set printer info - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param pol Policy handle on printer to set info. - * @param level Information level to set. - * @param ctr Pointer to structure holding printer information. - * @param command Specifies the action performed. See - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_13ua.asp - * for details. - * - */ - -WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr, uint32 command) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTER q; - SPOOL_R_SETPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) - goto done; - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - GetPrinterDriver() - ********************************************************************************/ -/** Get installed printer drivers for a given printer - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * may be NULL. - * - * @param pol Pointer to an open policy handle for the printer - * opened with cli_spoolss_open_printer_ex(). - * @param level Requested information level. - * @param env The print environment or archictecture. This is - * "Windows NT x86" for NT4. - * @param ctr Returned printer driver information. - */ - -WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *pol, uint32 level, - char *env, PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDRIVER2 q; - SPOOL_R_GETPRINTERDRIVER2 r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - fstrcpy (server, cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2, - &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - result = r.status; - - /* Return output parameters */ - - if (!W_ERROR_IS_OK(result)) - goto done; - - if (!ctr) - goto done; - - switch (level) { - case 1: - decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1); - break; - case 2: - decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2); - break; - case 3: - decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - EnumPrinterDrivers() - ********************************************************************************/ -/********************************************************************** - * Get installed printer drivers for a given printer - */ -WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 level, char *env, - uint32 *num_drivers, - PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDRIVERS q; - SPOOL_R_ENUMPRINTERDRIVERS r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0)) - goto done; - - if (needed) - *needed = r.needed; - - if (num_drivers) - *num_drivers = r.returned; - - result = r.status; - - /* Return output parameters */ - - if (W_ERROR_IS_OK(result) && (r.returned != 0)) { - *num_drivers = r.returned; - - switch (level) { - case 1: - decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1); - break; - case 2: - decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2); - break; - case 3: - decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3); - break; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - - -/********************************************************************************* - Win32 API - GetPrinterDriverDirectory() - ********************************************************************************/ -/********************************************************************** - * Get installed printer drivers for a given printer - */ -WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 level, char *env, - DRIVER_DIRECTORY_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDRIVERDIR q; - SPOOL_R_GETPRINTERDRIVERDIR r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY, - &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) { - switch (level) { - case 1: - decode_printerdriverdir_1(mem_ctx, r.buffer, 1, - &ctr->info1); - break; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - AddPrinterDriver() - ********************************************************************************/ -/********************************************************************** - * Install a printer driver - */ -WERROR cli_spoolss_addprinterdriver (struct cli_state *cli, - TALLOC_CTX *mem_ctx, uint32 level, - PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTERDRIVER q; - SPOOL_R_ADDPRINTERDRIVER r; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr); - - /* Marshall data and send request */ - - if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - AddPrinter() - ********************************************************************************/ -/********************************************************************** - * Install a printer - */ -WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 level, PRINTER_INFO_CTR*ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTEREX q; - SPOOL_R_ADDPRINTEREX r; - WERROR result = W_ERROR(ERRgeneral); - fstring server, - client, - user; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (client, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (client); - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - fstrcpy (user, cli->user_name); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, - level, ctr); - - /* Marshall data and send request */ - - if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - DeltePrinterDriver() - ********************************************************************************/ -/********************************************************************** - * Delete a Printer Driver from the server (does not remove - * the driver files - */ -WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli, - TALLOC_CTX *mem_ctx, char *arch, - char *driver) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_DELETEPRINTERDRIVER q; - SPOOL_R_DELETEPRINTERDRIVER r; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - - /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Write the request */ - - make_spoolss_q_deleteprinterdriver(mem_ctx, &q, server, arch, driver); - - /* Marshall data and send request */ - - if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - GetPrinterProcessorDirectory() - ********************************************************************************/ - -WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - char *name, char *environment, - fstring procdir) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTPROCESSORDIRECTORY q; - SPOOL_R_GETPRINTPROCESSORDIRECTORY r; - int level = 1; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - make_spoolss_q_getprintprocessordirectory( - &q, name, environment, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, - &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (W_ERROR_IS_OK(result)) - fstrcpy(procdir, "Not implemented!"); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Add a form to a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param level Form info level to add - should always be 1. - * @param form A pointer to the form to be added. - * - */ - -WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, uint32 level, FORM *form) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDFORM q; - SPOOL_R_ADDFORM r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_addform(&q, handle, level, form); - - /* Marshall data and send request */ - - if (!spoolss_io_q_addform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ADDFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_addform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Set a form on a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param level Form info level to set - should always be 1. - * @param form A pointer to the form to be set. - * - */ - -WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, uint32 level, char *form_name, - FORM *form) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETFORM q; - SPOOL_R_SETFORM r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_setform(&q, handle, level, form_name, form); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Get a form on a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param formname Name of the form to get - * @param level Form info level to get - should always be 1. - * - */ - -WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *handle, char *formname, uint32 level, - FORM_1 *form) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETFORM q; - SPOOL_R_GETFORM r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_getform(&q, handle, formname, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (W_ERROR_IS_OK(result)) - smb_io_form_1("", r.buffer, form, 0); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Delete a form on a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param form The name of the form to delete. - * - */ - -WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, char *form_name) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_DELETEFORM q; - SPOOL_R_DELETEFORM r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_deleteform(&q, handle, form_name); - - /* Marshall data and send request */ - - if (!spoolss_io_q_deleteform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_DELETEFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_deleteform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 num_forms, FORM_1 **forms) -{ - int i; - - *forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1)); - buffer->prs.data_offset = 0; - - for (i = 0; i < num_forms; i++) - smb_io_form_1("", buffer, &((*forms)[i]), 0); -} - -/** Enumerate forms - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * may be NULL. - * or cli_spoolss_addprinterex. - * @param level Form info level to get - should always be 1. - * @param handle Open policy handle - * - */ - -WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *handle, int level, uint32 *num_forms, - FORM_1 **forms) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMFORMS q; - SPOOL_R_ENUMFORMS r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enumforms(&q, handle, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMFORMS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumforms("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (num_forms) - *num_forms = r.numofforms; - - decode_forms_1(mem_ctx, r.buffer, *num_forms, forms); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_1 **jobs) -{ - uint32 i; - - *jobs = (JOB_INFO_1 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_1)); - buffer->prs.data_offset = 0; - - for (i = 0; i < num_jobs; i++) - smb_io_job_info_1("", buffer, &((*jobs)[i]), 0); -} - -static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_2 **jobs) -{ - uint32 i; - - *jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2)); - buffer->prs.data_offset = 0; - - for (i = 0; i < num_jobs; i++) - smb_io_job_info_2("", buffer, &((*jobs)[i]), 0); -} - -/* Enumerate jobs */ - -WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *hnd, uint32 level, uint32 firstjob, - uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMJOBS q; - SPOOL_R_ENUMJOBS r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enumjobs(&q, hnd, firstjob, num_jobs, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumjobs("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMJOBS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumjobs("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - *returned = r.returned; - - switch(level) { - case 1: - decode_jobs_1(mem_ctx, r.buffer, r.returned, - ctr->job.job_info_1); - break; - case 2: - decode_jobs_2(mem_ctx, r.buffer, r.returned, - ctr->job.job_info_2); - break; - default: - DEBUG(3, ("unsupported info level %d", level)); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set job */ - -WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 jobid, uint32 level, - uint32 command) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETJOB q; - SPOOL_R_SETJOB r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_setjob(&q, hnd, jobid, level, command); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setjob("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETJOB, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setjob("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Get job */ - -WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *hnd, uint32 jobid, uint32 level, - JOB_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETJOB q; - SPOOL_R_GETJOB r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_getjob(&q, hnd, jobid, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getjob("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETJOB, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getjob("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - switch(level) { - case 1: - decode_jobs_1(mem_ctx, r.buffer, 1, ctr->job.job_info_1); - break; - case 2: - decode_jobs_2(mem_ctx, r.buffer, 1, ctr->job.job_info_2); - break; - default: - DEBUG(3, ("unsupported info level %d", level)); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Startpageprinter. Sent to notify the spooler when a page is about to be - sent to a printer. */ - -WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_STARTPAGEPRINTER q; - SPOOL_R_STARTPAGEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_startpageprinter(&q, hnd); - - /* Marshall data and send request */ - - if (!spoolss_io_q_startpageprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_startpageprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Endpageprinter. Sent to notify the spooler when a page has finished - being sent to a printer. */ - -WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENDPAGEPRINTER q; - SPOOL_R_ENDPAGEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_endpageprinter(&q, hnd); - - /* Marshall data and send request */ - - if (!spoolss_io_q_endpageprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_endpageprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Startdocprinter. Sent to notify the spooler that a document is about - to be spooled for printing. */ - -WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *docname, - char *outputfile, char *datatype, - uint32 *jobid) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_STARTDOCPRINTER q; - SPOOL_R_STARTDOCPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - uint32 level = 1; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_startdocprinter(&q, hnd, level, docname, outputfile, - datatype); - - /* Marshall data and send request */ - - if (!spoolss_io_q_startdocprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_startdocprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *jobid = r.jobid; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enddocprinter. Sent to notify the spooler that a document has finished - being spooled. */ - -WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENDDOCPRINTER q; - SPOOL_R_ENDDOCPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enddocprinter(&q, hnd); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enddocprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enddocprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Get printer data */ - -WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *hnd, char *valuename, - uint32 *data_type, char **data, - uint32 *data_size) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDATA q; - SPOOL_R_GETPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_getprinterdata(&q, hnd, valuename, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (needed) - *needed = r.needed; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - /* Return output parameters */ - - if (data_type) - *data_type = r.type; - - if (data) { - *data = (char *)talloc(mem_ctx, r.needed); - memcpy(*data, r.data, r.needed); - } - - if (data_size) - *data_size = r.needed; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set printer data */ - -WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *value, - uint32 data_type, char *data, - uint32 data_size) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTERDATA q; - SPOOL_R_SETPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_setprinterdata(&q, hnd, value, data, data_size); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enum printer data */ - -WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 ndx, - uint32 value_offered, uint32 data_offered, - uint32 *value_needed, uint32 *data_needed, - char **value, uint32 *data_type, char **data, - uint32 *data_size) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDATA q; - SPOOL_R_ENUMPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enumprinterdata(&q, hnd, ndx, value_offered, data_offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - /* Return data */ - - if (value_needed) - *value_needed = r.realvaluesize; - - if (data_needed) - *data_needed = r.realdatasize; - - if (data_type) - *data_type = r.type; - - if (value) { - fstring the_value; - - rpcstr_pull(the_value, r.value, sizeof(the_value), -1, - STR_TERMINATE); - - *value = talloc_strdup(mem_ctx, the_value); - } - - if (data) - *data = talloc_memdup(mem_ctx, r.data, r.realdatasize); - - if (data_size) - *data_size = r.realdatasize; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Write data to printer */ - -WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 data_size, char *data, - uint32 *num_written) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_WRITEPRINTER q; - SPOOL_R_WRITEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_writeprinter(&q, hnd, data_size, data); - - /* Marshall data and send request */ - - if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - if (num_written) - *num_written = r.buffer_written; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Delete printer data */ - -WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *valuename) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_DELETEPRINTERDATA q; - SPOOL_R_DELETEPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_deleteprinterdata(&q, hnd, valuename); - - /* Marshall data and send request */ - - if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** @} **/ diff --git a/source3/libsmb/cli_spoolss_notify.c b/source3/libsmb/cli_spoolss_notify.c deleted file mode 100644 index 922b0fbb1d..0000000000 --- a/source3/libsmb/cli_spoolss_notify.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - - Copyright (C) Gerald Carter 2001-2002, - Copyright (C) Tim Potter 2000-2002, - Copyright (C) Andrew Tridgell 1994-2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Jean-Francois Micouleau 1999-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 - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* - * SPOOLSS Client RPC's used by servers as the notification - * back channel. - */ - -/* Send a ReplyOpenPrinter request. This rpc is made by the printer - server to the printer client in response to a rffpcnex request. - The rrfpcnex request names a printer and a handle (the printerlocal - value) and this rpc establishes a back-channel over which printer - notifications are performed. */ - -WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *printer, uint32 printerlocal, uint32 type, - POLICY_HND *handle) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_REPLYOPENPRINTER q; - SPOOL_R_REPLYOPENPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type); - - /* Marshall data and send request */ - - if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0)) - goto done; - - /* Return result */ - - memcpy(handle, &r.handle, sizeof(r.handle)); - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Close a back-channel notification connection */ - -WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_REPLYCLOSEPRINTER q; - SPOOL_R_REPLYCLOSEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_reply_closeprinter(&q, handle); - - /* Marshall data and send request */ - - if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0)) - goto done; - - /* Return result */ - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************* - This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change - notification event when the registration **did not** use - SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor. - Also see cli_spolss_reply_rrpcn() - *********************************************************************/ - -WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 condition, uint32 change_id) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ROUTERREPLYPRINTER q; - SPOOL_R_ROUTERREPLYPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_routerreplyprinter(&q, pol, condition, change_id); - - /* Marshall data and send request */ - - if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************* - This SPOOLSS_REPLY_RRPCN function is used to send a change - notification event when the registration **did** use - SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor - Also see cli_spoolss_routereplyprinter() - *********************************************************************/ - -WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 notify_data_len, - SPOOL_NOTIFY_INFO_DATA *notify_data, - uint32 change_low, uint32 change_high) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_REPLY_RRPCN q; - SPOOL_R_REPLY_RRPCN r; - WERROR result = W_ERROR(ERRgeneral); - SPOOL_NOTIFY_INFO notify_info; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - ZERO_STRUCT(notify_info); - - /* Initialise input parameters */ - - notify_info.version = 0x2; - notify_info.flags = 0x00020000; /* ?? */ - notify_info.count = notify_data_len; - notify_info.data = notify_data; - - /* create and send a MSRPC command with api */ - /* store the parameters */ - - make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high, - ¬ify_info); - - /* Marshall data and send request */ - - if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0)) - goto done; - - if (r.unknown0 == 0x00080000) - DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n")); - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c deleted file mode 100644 index 1bdd19620b..0000000000 --- a/source3/libsmb/cli_srvsvc.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - Unix SMB/CIFS implementation. - NT Domain Authentication SMB / MSRPC client - Copyright (C) Andrew Tridgell 1994-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Tim Potter 2001 - Copyright (C) Jim McDonough 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 switch_value, SRV_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SRV_GET_INFO q; - SRV_R_NET_SRV_GET_INFO r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value); - - /* Marshall data and send request */ - - if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 info_level, SRV_SHARE_INFO_CTR *ctr, - int preferred_len, ENUM_HND *hnd) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SHARE_ENUM q; - SRV_R_NET_SHARE_ENUM r; - WERROR result = W_ERROR(ERRgeneral); - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_share_enum( - &q, cli->srv_name_slash, info_level, preferred_len, hnd); - - /* Marshall data and send request */ - - if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_share_enum("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - /* Oh yuck yuck yuck - we have to copy all the info out of the - SRV_SHARE_INFO_CTR in the SRV_R_NET_SHARE_ENUM as when we do a - prs_mem_free() it will all be invalidated. The various share - info structures suck badly too. This really is gross. */ - - ZERO_STRUCTP(ctr); - - if (!r.ctr.num_entries) - goto done; - - ctr->info_level = info_level; - ctr->num_entries = r.ctr.num_entries; - - switch(info_level) { - case 1: - ctr->share.info1 = (SRV_SHARE_INFO_1 *)talloc( - mem_ctx, sizeof(SRV_SHARE_INFO_1) * ctr->num_entries); - - memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1)); - - for (i = 0; i < ctr->num_entries; i++) { - SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i]; - char *s; - - /* Copy pointer crap */ - - memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1, - sizeof(SH_INFO_1)); - - /* Duplicate strings */ - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname); - if (s) - init_unistr2(&info1->info_1_str.uni_netname, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark); - if (s) - init_unistr2(&info1->info_1_str.uni_remark, s, strlen(s) + 1); - - } - - break; - case 2: - ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc( - mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries); - - memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2)); - - for (i = 0; i < ctr->num_entries; i++) { - SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i]; - char *s; - - /* Copy pointer crap */ - - memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2, - sizeof(SH_INFO_2)); - - /* Duplicate strings */ - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname); - if (s) - init_unistr2(&info2->info_2_str.uni_netname, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark); - if (s) - init_unistr2(&info2->info_2_str.uni_remark, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path); - if (s) - init_unistr2(&info2->info_2_str.uni_path, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd); - if (s) - init_unistr2(&info2->info_2_str.uni_passwd, s, strlen(s) + 1); - } - break; - } - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx, - const char *sharename) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SHARE_DEL q; - SRV_R_NET_SHARE_DEL r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename); - - /* Marshall data and send request */ - - if (!srv_io_q_net_share_del("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_share_del("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *netname, uint32 type, char *remark, - uint32 perms, uint32 max_uses, uint32 num_uses, - char *path, char *passwd) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SHARE_ADD q; - SRV_R_NET_SHARE_ADD r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark, - perms, max_uses, num_uses, path, passwd); - - /* Marshall data and send request */ - - if (!srv_io_q_net_share_add("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_share_add("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *server, TIME_OF_DAY_INFO *tod) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_REMOTE_TOD q; - SRV_R_NET_REMOTE_TOD r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_remote_tod(&q, cli->srv_name_slash); - - /* Marshall data and send request */ - - if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - r.tod = tod; - - if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 file_level, const char *user_name, - SRV_FILE_INFO_CTR *ctr, int preferred_len, - ENUM_HND *hnd) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_FILE_ENUM q; - SRV_R_NET_FILE_ENUM r; - WERROR result = W_ERROR(ERRgeneral); - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name, - file_level, ctr, preferred_len, hnd); - - /* Marshall data and send request */ - - if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_file_enum("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - /* copy the data over to the ctr */ - - ZERO_STRUCTP(ctr); - - ctr->switch_value = file_level; - - ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries; - - switch(file_level) { - case 3: - ctr->file.info3 = (SRV_FILE_INFO_3 *)talloc( - mem_ctx, sizeof(SRV_FILE_INFO_3) * ctr->num_entries); - - memset(ctr->file.info3, 0, - sizeof(SRV_FILE_INFO_3) * ctr->num_entries); - - for (i = 0; i < r.ctr.num_entries; i++) { - SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i]; - char *s; - - /* Copy pointer crap */ - - memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3, - sizeof(FILE_INFO_3)); - - /* Duplicate strings */ - - s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name); - if (s) - init_unistr2(&info3->info_3_str.uni_path_name, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name); - if (s) - init_unistr2(&info3->info_3_str.uni_user_name, s, strlen(s) + 1); - - } - - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 file_id) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_FILE_CLOSE q; - SRV_R_NET_FILE_CLOSE r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_file_close(&q, cli->srv_name_slash, file_id); - - /* Marshall data and send request */ - - if (!srv_io_q_net_file_close("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_file_close("", &r, &rbuf, 0)) - goto done; - - result = r.status; - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return result; -} diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c deleted file mode 100644 index 97b948bf62..0000000000 --- a/source3/libsmb/cli_wkssvc.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - Unix SMB/CIFS implementation. - NT Domain Authentication SMB / MSRPC client - Copyright (C) Andrew Tridgell 1994-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Tim Potter 2001 - Copytight (C) Rafal Szczesniak 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** - * WksQueryInfo rpc call (like query for server's capabilities) - * - * @param initialised client structure with \PIPE\wkssvc opened - * @param mem_ctx memory context assigned to this rpc binding - * @param wks100 WksQueryInfo structure - * - * @return NTSTATUS of rpc call - */ - -NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - WKS_INFO_100 *wks100) -{ - prs_struct buf; - prs_struct rbuf; - WKS_Q_QUERY_INFO q_o; - WKS_R_QUERY_INFO r_o; - - if (cli == NULL || wks100 == NULL) - return NT_STATUS_UNSUCCESSFUL; - - /* init rpc parse structures */ - prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - DEBUG(4, ("WksQueryInfo\n")); - - /* init query structure with rpc call arguments */ - init_wks_q_query_info(&q_o, cli->desthost, 100); - - /* marshall data */ - if (!wks_io_q_query_info("", &q_o, &buf, 0)) { - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; - } - - /* actual rpc call over \PIPE\wkssvc */ - if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) { - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; - } - - prs_mem_free(&buf); - - r_o.wks100 = wks100; - - /* get call results from response buffer */ - if (!wks_io_r_query_info("", &r_o, &rbuf, 0)) { - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; - } - - /* check returnet status code */ - if (NT_STATUS_IS_ERR(r_o.status)) { - /* report the error */ - DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r_o.status))); - prs_mem_free(&rbuf); - return r_o.status; - } - - /* do clean up */ - prs_mem_free(&rbuf); - - return NT_STATUS_OK; -} - -- cgit From c7597b144a633948e0fed3c5916fe5f36bb4cc99 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Aug 2002 01:55:44 +0000 Subject: fixed a bug where we were truncating the returned names in a netbios name status query to 14 bytes, so we could not join a DC who had a netbios name of 15 bytes in length. (This used to be commit a7588f21c24dac833f098c48e2337c100cf75ba4) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index ae58c3a062..141581e261 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -196,7 +196,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t if (i == count) goto done; - pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE); + pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE); result = True; done: -- cgit From ab9ff0fa73f33c064a39859e39fa79af77cc088f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Aug 2002 02:47:46 +0000 Subject: This fixes a number of ADS problems, particularly with netbiosless setups. - split up the ads structure into logical pieces. This makes it much easier to keep things like the authentication realm and the server realm separate (they can be different). - allow ads callers to specify that no sasl bind should be performed (used by "net ads info" for example) - fix an error with handing ADS_ERROR_SYSTEM() when errno is 0 - completely rewrote the code for finding the LDAP server. Now try DNS methods first, and try all DNS servers returned from the SRV DNS query, sorted by closeness to our interfaces (using the same sort code as we use in replies from WINS servers). This allows us to cope with ADS DCs that are down, and ensures we don't pick one that is on the other side of the country unless absolutely necessary. - recognise dnsRecords as binary when displaying them - cope with the realm not being configured in smb.conf (work it out from the LDAP server) - look at the trustDirection when looking up trusted domains and don't include trusts that trust our domains but we don't trust theirs. - use LDAP to query the alternate (netbios) name for a realm, and make sure that both and long and short forms of the name are accepted by winbindd. Use the short form by default for listing users/groups. - rescan the list of trusted domains every 5 minutes in case new trust relationships are added while winbindd is running - include transient trust relationships (ie. C trusts B, B trusts A, so C trusts A) in winbindd. - don't do a gratuituous node status lookup when finding an ADS DC (we don't need it and it could fail) - remove unused sid_to_distinguished_name function - make sure we find the allternate name of our primary domain when operating with a netbiosless ADS DC (using LDAP to do the lookup) - fixed the rpc trusted domain enumeration to support up to approx 2000 trusted domains (the old limit was 3) - use the IP for the remote_machine (%m) macro when the client doesn't supply us with a name via a netbios session request (eg. port 445) - if the client uses SPNEGO then use the machine name from the SPNEGO auth packet for remote_machine (%m) macro - add new 'net ads workgroup' command to find the netbios workgroup name for a realm (This used to be commit e358d7b24c86a46d8c361b9e32a25d4f71a6dc00) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 141581e261..3382ce4f4a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -216,7 +216,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t /* comparison function used by sort_ip_list */ -static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) +int ip_compare(struct in_addr *ip1, struct in_addr *ip2) { int max_bits1=0, max_bits2=0; int num_interfaces = iface_count(); -- cgit From ec7927a1445cebcfb58a0f613dd9d601390c8c76 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 15 Aug 2002 12:18:25 +0000 Subject: Fix NTLMSSP challenge command and auth response. We can now service joins from win2k AND still use SPNEGO (provided you don't build with kerberos...I still have to fix that, as we are not properly falling back). (This used to be commit 1f9b3d46c7c99e84b2983220f79613b7420c5ced) --- source3/libsmb/clispnego.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 469b946088..16702c375b 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jim McDonough 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 @@ -439,6 +440,28 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) return True; } +/* + generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. +*/ +DATA_BLOB spnego_gen_auth_response(void) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_CONTEXT(1)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_write_enumerated(&data, 0); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + ret = data_blob(data.data, data.length); + asn1_free(&data); + return ret; +} /* this is a tiny msrpc packet generator. I am only using this to @@ -449,6 +472,7 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) format specifiers are: U = unicode string (input is unix string) + a = address (1 byte type, 1 byte length, unicode string, all inline) B = data blob (pointer + length) b = data blob in header (pointer + length) d = word (4 bytes) @@ -473,6 +497,11 @@ BOOL msrpc_gen(DATA_BLOB *blob, head_size += 8; data_size += str_charnum(s) * 2; break; + case 'a': + n = va_arg(ap, int); + s = va_arg(ap, char *); + data_size += (str_charnum(s) * 2) + 4; + break; case 'B': b = va_arg(ap, uint8 *); head_size += 8; @@ -512,6 +541,19 @@ BOOL msrpc_gen(DATA_BLOB *blob, push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); data_ofs += n*2; break; + case 'a': + n = va_arg(ap, int); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); + } + data_ofs += n*2; + break; + case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); @@ -550,6 +592,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, format specifiers are: U = unicode string (output is unix string) + A = ascii string B = data blob b = data blob in header d = word (4 bytes) @@ -584,6 +627,24 @@ BOOL msrpc_parse(DATA_BLOB *blob, STR_UNICODE|STR_NOALIGN); (*ps) = strdup(p); break; + case 'A': + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + ps = va_arg(ap, char **); + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, -1, + len1, STR_ASCII|STR_NOALIGN); + (*ps) = strdup(p); + } else { + (*ps) = NULL; + } + break; case 'B': len1 = SVAL(blob->data, head_ofs); head_ofs += 2; len2 = SVAL(blob->data, head_ofs); head_ofs += 2; -- cgit From 88d321becdcff10f52a629946fb300d158fcc2fa Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 16 Aug 2002 00:25:48 +0000 Subject: Merge of netbios namecache code from APPLIANCE_HEAD. Tridge suggested a generic caching mechanism for Samba to avoid the proliferation of little cache files hanging around limpet like in the locks directory. Someone should probably implement this at some stage. (This used to be commit dad31483b3bd1790356ef1e40ac62624a403bce8) --- source3/libsmb/namecache.c | 252 +++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/namequery.c | 28 ++++- 2 files changed, 276 insertions(+), 4 deletions(-) create mode 100644 source3/libsmb/namecache.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c new file mode 100644 index 0000000000..fc09d8eac2 --- /dev/null +++ b/source3/libsmb/namecache.c @@ -0,0 +1,252 @@ +/* + Unix SMB/CIFS implementation. + + NetBIOS name cache module. + + Copyright (C) Tim Potter, 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +static BOOL done_namecache_init; +static BOOL enable_namecache; +static TDB_CONTEXT *namecache_tdb; + +struct nc_value { + time_t expiry; /* When entry expires */ + int count; /* Number of addresses */ + struct in_addr ip_list[0]; /* Address list */ +}; + +/* Initialise namecache system */ + +void namecache_enable(void) +{ + /* Check if we have been here before, or name caching disabled + by setting the name cache timeout to zero. */ + + if (done_namecache_init) + return; + + done_namecache_init = True; + + if (lp_name_cache_timeout() == 0) { + DEBUG(5, ("namecache_init: disabling netbios name cache\n")); + return; + } + + /* Open namecache tdb in read/write or readonly mode */ + + namecache_tdb = tdb_open_log( + lock_path("namecache.tdb"), 0, + TDB_DEFAULT, O_RDWR | O_CREAT, 0644); + + if (!namecache_tdb) { + DEBUG(5, ("namecache_init: could not open %s\n", + lock_path("namecache.tdb"))); + return; + } + + DEBUG(5, ("namecache_init: enabling netbios namecache, timeout %d " + "seconds\n", lp_name_cache_timeout())); + + enable_namecache = True; +} + +/* Return a key for a name and name type. The caller must free + retval.dptr when finished. */ + +static TDB_DATA namecache_key(const char *name, int name_type) +{ + TDB_DATA retval; + char *keystr; + + asprintf(&keystr, "%s#%02X", strupper_static(name), name_type); + + retval.dsize = strlen(keystr) + 1; + retval.dptr = keystr; + + return retval; +} + +/* Return a data value for an IP list. The caller must free + retval.dptr when finished. */ + +static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, + time_t expiry) +{ + TDB_DATA retval; + struct nc_value *value; + int size; + + size = sizeof(struct nc_value) + sizeof(struct in_addr) * + num_names; + + value = (struct nc_value *)malloc(size); + + value->expiry = expiry; + value->count = num_names; + + memcpy(value->ip_list, ip_list, num_names * sizeof(struct in_addr)); + + retval.dptr = (char *)value; + retval.dsize = size; + + return retval; +} + +/* Store a name in the name cache */ + +void namecache_store(const char *name, int name_type, + int num_names, struct in_addr *ip_list) +{ + TDB_DATA key, value; + time_t expiry; + int i; + + if (!enable_namecache) + return; + + DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ", + num_names, num_names == 1 ? "": "es", name, name_type)); + + for (i = 0; i < num_names; i++) + DEBUGADD(5, ("%s%s", inet_ntoa(ip_list[i]), + i == (num_names - 1) ? "" : ", ")); + + DEBUGADD(5, ("\n")); + + key = namecache_key(name, name_type); + + /* Cache pdc location or dc lists for only a little while + otherwise if we lock on to a bad DC we can potentially be + out of action for the entire cache timeout time! */ + + if (name_type != 0x1b || name_type != 0x1c) + expiry = time(NULL) + 10; + else + expiry = time(NULL) + lp_name_cache_timeout(); + + value = namecache_value(ip_list, num_names, expiry); + + tdb_store(namecache_tdb, key, value, TDB_REPLACE); + + free(key.dptr); + free(value.dptr); +} + +/* Look up a name in the name cache. Return a mallocated list of IP + addresses if the name is contained in the cache. */ + +BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, + int *num_names) +{ + TDB_DATA key, value; + struct nc_value *data; + time_t now; + int i; + + if (!enable_namecache) + return False; + + /* Read value */ + + key = namecache_key(name, name_type); + + value = tdb_fetch(namecache_tdb, key); + + if (!value.dptr) { + DEBUG(5, ("namecache_fetch: %s#%02x not found\n", + name, name_type)); + goto done; + } + + data = (struct nc_value *)value.dptr; + + /* Check expiry time */ + + now = time(NULL); + + if (now > data->expiry) { + + DEBUG(5, ("namecache_fetch: entry for %s#%02x expired\n", + name, name_type)); + + tdb_delete(namecache_tdb, key); + + value = tdb_null; + + goto done; + } + + if ((data->expiry - now) > lp_name_cache_timeout()) { + + /* Someone may have changed the system time on us */ + + DEBUG(5, ("namecache_fetch: entry for %s#%02x has bad expiry\n", + name, name_type)); + + tdb_delete(namecache_tdb, key); + + value = tdb_null; + + goto done; + } + + /* Extract and return namelist */ + + *ip_list = (struct in_addr *)malloc( + sizeof(struct in_addr) * data->count); + + memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * + data->count); + + *num_names = data->count; + + DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ", + *num_names, *num_names == 1 ? "" : "es", name, name_type)); + + for (i = 0; i < *num_names; i++) + DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]), + i == (*num_names - 1) ? "" : ", ")); + + DEBUGADD(5, ("\n")); + +done: + SAFE_FREE(key.dptr); + SAFE_FREE(value.dptr); + + return value.dsize > 0; +} + +/* Flush all names from the name cache */ + +void namecache_flush(void) +{ + int result; + + if (!namecache_tdb) + return; + + result = tdb_traverse(namecache_tdb, tdb_traverse_delete_fn, NULL); + + if (result == -1) + DEBUG(5, ("namecache_flush: error deleting cache entries\n")); + else + DEBUG(5, ("namecache_flush: deleted %d cache entr%s\n", + result, result == 1 ? "y" : "ies")); +} diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 3382ce4f4a..40a353fa8b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -783,7 +783,7 @@ static BOOL resolve_hosts(const char *name, *********************************************************/ static BOOL internal_resolve_name(const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) + struct in_addr **return_iplist, int *return_count) { pstring name_resolve_list; fstring tok; @@ -816,6 +816,15 @@ static BOOL internal_resolve_name(const char *name, int name_type, return True; } + /* Check netbios name cache */ + + if (namecache_fetch(name, name_type, return_iplist, return_count)) { + + /* This could be a negative response */ + + return (*return_count > 0); + } + pstrcpy(name_resolve_list, lp_name_resolve_order()); ptr = name_resolve_list; if (!ptr || !*ptr) @@ -823,9 +832,16 @@ static BOOL internal_resolve_name(const char *name, int name_type, while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { - if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) { - result = True; - goto done; + if (name_type == 0x20) { + if (resolve_hosts(name, return_iplist, return_count)) { + result = True; + goto done; + } else { + + /* Store negative lookup result */ + + namecache_store(name, name_type, 0, NULL); + } } } else if(strequal( tok, "lmhosts")) { if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { @@ -897,6 +913,10 @@ static BOOL internal_resolve_name(const char *name, int name_type, *return_iplist = nodupes_iplist; *return_count = nodupes_count; } + + /* Save in name cache */ + + namecache_store(name, name_type, *return_count, *return_iplist); /* Display some debugging info */ -- cgit