Beispiel #1
0
bool cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
{
	char *rparam = NULL;
	char *rdata = NULL;
	char *p;
	unsigned int rdrcnt,rprcnt;
	char param[1024];

	memset(param, 0, sizeof(param));

	/* send a SMBtrans command with api NetWkstaUserLogon */
	p = param;
	SSVAL(p,0,132); /* api number */
	p += 2;
	strlcpy(p,"OOWb54WrLh",sizeof(param)-PTR_DIFF(p,param));
	p = skip_string(param,sizeof(param),p);
	strlcpy(p,"WB21BWDWWDDDDDDDzzzD",sizeof(param)-PTR_DIFF(p,param));
	p = skip_string(param,sizeof(param),p);
	SSVAL(p,0,1);
	p += 2;
	strlcpy(p,user,sizeof(param)-PTR_DIFF(p,param));
	strupper_m(p);
	p += 21;
	p++;
	p += 15;
	p++;
	strlcpy(p, workstation,sizeof(param)-PTR_DIFF(p,param));
	strupper_m(p);
	p += 16;
	SSVAL(p, 0, CLI_BUFFER_SIZE);
	p += 2;
	SSVAL(p, 0, CLI_BUFFER_SIZE);
	p += 2;

	if (cli_api(cli,
                    param, PTR_DIFF(p,param),1024,  /* param, length, max */
                    NULL, 0, CLI_BUFFER_SIZE,           /* data, length, max */
                    &rparam, &rprcnt,               /* return params, return size */
                    &rdata, &rdrcnt                 /* return data, return size */
                   )) {
		cli->rap_error = rparam? SVAL(rparam,0) : -1;
		p = rdata;

		if (cli->rap_error == 0) {
			DEBUG(4,("NetWkstaUserLogon success\n"));
			/*
			 * The cli->privileges = SVAL(p, 24); field was set here
			 * but it was not use anywhere else.
			 */
			/* The cli->eff_name field used to be set here
	                   but it wasn't used anywhere else. */
		} else {
			DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error));
		}
	}

	SAFE_FREE(rparam);
	SAFE_FREE(rdata);
	return (cli->rap_error == 0);
}
Beispiel #2
0
int cli_printjob_del(struct cli_state *cli, int job)
{
	char *rparam = NULL;
	char *rdata = NULL;
	char *p;
	unsigned int rdrcnt,rprcnt;
	int ret = -1;
	char param[1024];

	memset(param,'\0',sizeof(param));

	p = param;
	SSVAL(p,0,81);		/* DosPrintJobDel() */
	p += 2;
	strlcpy_base(p,"W", param,sizeof(param));
	p = skip_string(param,sizeof(param),p);
	strlcpy_base(p,"", param,sizeof(param));
	p = skip_string(param,sizeof(param),p);
	SSVAL(p,0,job);
	p += 2;

	if (cli_api(cli,
		    param, PTR_DIFF(p,param), 1024,  /* Param, length, maxlen */
		    NULL, 0, CLI_BUFFER_SIZE,            /* data, length, maxlen */
		    &rparam, &rprcnt,                /* return params, length */
		    &rdata, &rdrcnt)) {               /* return data, length */
		ret = SVAL(rparam,0);
	}

	SAFE_FREE(rparam);
	SAFE_FREE(rdata);

	return ret;
}
Beispiel #3
0
bool cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
                             const char *old_password)
{
	char param[1024];
	unsigned char data[532];
	char *p = param;
	unsigned char old_pw_hash[16];
	unsigned char new_pw_hash[16];
	unsigned int data_len;
	unsigned int param_len = 0;
	char *rparam = NULL;
	char *rdata = NULL;
	unsigned int rprcnt, rdrcnt;

	if (strlen(user) >= sizeof(fstring)-1) {
		DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user));
		return False;
	}

	SSVAL(p,0,214); /* SamOEMChangePassword command. */
	p += 2;
	strlcpy(p, "zsT", sizeof(param)-PTR_DIFF(p,param));
	p = skip_string(param,sizeof(param),p);
	strlcpy(p, "B516B16", sizeof(param)-PTR_DIFF(p,param));
	p = skip_string(param,sizeof(param),p);
	strlcpy(p,user, sizeof(param)-PTR_DIFF(p,param));
	p = skip_string(param,sizeof(param),p);
	SSVAL(p,0,532);
	p += 2;

	param_len = PTR_DIFF(p,param);

	/*
	 * Get the Lanman hash of the old password, we
	 * use this as the key to make_oem_passwd_hash().
	 */
	E_deshash(old_password, old_pw_hash);

	encode_pw_buffer(data, new_password, STR_ASCII);

#ifdef DEBUG_PASSWORD
	DEBUG(100,("make_oem_passwd_hash\n"));
	dump_data(100, data, 516);
#endif
	arcfour_crypt( (unsigned char *)data, (unsigned char *)old_pw_hash, 516);

	/*
	 * Now place the old password hash in the data.
	 */
	E_deshash(new_password, new_pw_hash);

	E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]);

	data_len = 532;

	if (!cli_api(cli,
		     param, param_len, 4,		/* param, length, max */
		     (char *)data, data_len, 0,		/* data, length, max */
		     &rparam, &rprcnt,
		     &rdata, &rdrcnt)) {
		DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n",
			user ));
		return False;
	}

	if (rparam) {
		cli->rap_error = SVAL(rparam,0);
	}

	SAFE_FREE(rparam);
	SAFE_FREE(rdata);

	return (cli->rap_error == 0);
}
Beispiel #4
0
bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32_t stype,
		       void (*fn)(const char *, uint32_t, const char *, void *),
		       void *state)
{
	char *rparam = NULL;
	char *rdata = NULL;
	char *rdata_end = NULL;
	unsigned int rdrcnt,rprcnt;
	char *p;
	char param[1024];
	int uLevel = 1;
	size_t len;
	uint32_t func = RAP_NetServerEnum2;
	char *last_entry = NULL;
	int total_cnt = 0;
	int return_cnt = 0;
	int res;

	errno = 0; /* reset */

	/*
	 * This may take more than one transaction, so we should loop until
	 * we no longer get a more data to process or we have all of the
	 * items.
	 */
	do {
		/* send a SMBtrans command with api NetServerEnum */
	        p = param;
		SIVAL(p,0,func); /* api number */
	        p += 2;

		if (func == RAP_NetServerEnum3) {
			strlcpy(p,"WrLehDzz", sizeof(param)-PTR_DIFF(p,param));
		} else {
			strlcpy(p,"WrLehDz", sizeof(param)-PTR_DIFF(p,param));
		}

		p = skip_string(param, sizeof(param), p);
		strlcpy(p,"B16BBDz", sizeof(param)-PTR_DIFF(p,param));

		p = skip_string(param, sizeof(param), p);
		SSVAL(p,0,uLevel);
		SSVAL(p,2,CLI_BUFFER_SIZE);
		p += 4;
		SIVAL(p,0,stype);
		p += 4;

		/* If we have more data, tell the server where
		 * to continue from.
		 */
		len = push_ascii(p,
				workgroup,
				sizeof(param) - PTR_DIFF(p,param) - 1,
				STR_TERMINATE|STR_UPPER);

		if (len == 0) {
			SAFE_FREE(last_entry);
			return false;
		}
		p += len;

		if (func == RAP_NetServerEnum3) {
			len = push_ascii(p,
					last_entry ? last_entry : "",
					sizeof(param) - PTR_DIFF(p,param) - 1,
					STR_TERMINATE);

			if (len == 0) {
				SAFE_FREE(last_entry);
				return false;
			}
			p += len;
		}

		/* Next time through we need to use the continue api */
		func = RAP_NetServerEnum3;

		if (!cli_api(cli,
			param, PTR_DIFF(p,param), 8, /* params, length, max */
			NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
		            &rparam, &rprcnt, /* return params, return size */
		            &rdata, &rdrcnt)) { /* return data, return size */

			/* break out of the loop on error */
		        res = -1;
		        break;
		}

		rdata_end = rdata + rdrcnt;
		res = rparam ? SVAL(rparam,0) : -1;

		if (res == 0 || res == ERRmoredata ||
                    (res != -1 && cli_errno(cli) == 0)) {
			char *sname = NULL;
			int i, count;
			int converter=SVAL(rparam,2);

			/* Get the number of items returned in this buffer */
			count = SVAL(rparam, 4);

			/* The next field contains the number of items left,
			 * including those returned in this buffer. So the
			 * first time through this should contain all of the
			 * entries.
			 */
			if (total_cnt == 0) {
			        total_cnt = SVAL(rparam, 6);
			}

			/* Keep track of how many we have read */
			return_cnt += count;
			p = rdata;

			/* The last name in the previous NetServerEnum reply is
			 * sent back to server in the NetServerEnum3 request
			 * (last_entry). The next reply should repeat this entry
			 * as the first element. We have no proof that this is
			 * always true, but from traces that seems to be the
			 * behavior from Window Servers. So first lets do a lot
			 * of checking, just being paranoid. If the string
			 * matches then we already saw this entry so skip it.
			 *
			 * NOTE: sv1_name field must be null terminated and has
			 * a max size of 16 (NetBIOS Name).
			 */
			if (last_entry && count && p &&
				(strncmp(last_entry, p, 16) == 0)) {
			    count -= 1; /* Skip this entry */
			    return_cnt = -1; /* Not part of total, so don't count. */
			    p = rdata + 26; /* Skip the whole record */
			}

			for (i = 0; i < count; i++, p += 26) {
				int comment_offset;
				const char *cmnt;
				const char *p1;
				char *s1, *s2;
				TALLOC_CTX *frame = talloc_stackframe();
				uint32_t entry_stype;

				if (p + 26 > rdata_end) {
					TALLOC_FREE(frame);
					break;
				}

				sname = p;
				comment_offset = (IVAL(p,22) & 0xFFFF)-converter;
				cmnt = comment_offset?(rdata+comment_offset):"";

				if (comment_offset < 0 || comment_offset >= (int)rdrcnt) {
					TALLOC_FREE(frame);
					continue;
				}

				/* Work out the comment length. */
				for (p1 = cmnt, len = 0; *p1 &&
						p1 < rdata_end; len++)
					p1++;
				if (!*p1) {
					len++;
				}

				entry_stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;

				pull_string_talloc(frame,rdata,0,
					&s1,sname,16,STR_ASCII);
				pull_string_talloc(frame,rdata,0,
					&s2,cmnt,len,STR_ASCII);

				if (!s1 || !s2) {
					TALLOC_FREE(frame);
					continue;
				}

				fn(s1, entry_stype, s2, state);
				TALLOC_FREE(frame);
			}

			/* We are done with the old last entry, so now we can free it */
			if (last_entry) {
			        SAFE_FREE(last_entry); /* This will set it to null */
			}

			/* We always make a copy of  the last entry if we have one */
			if (sname) {
			        last_entry = smb_xstrdup(sname);
			}

			/* If we have more data, but no last entry then error out */
			if (!last_entry && (res == ERRmoredata)) {
			        errno = EINVAL;
			        res = 0;
			}

		}

		SAFE_FREE(rparam);
		SAFE_FREE(rdata);
	} while ((res == ERRmoredata) && (total_cnt > return_cnt));

	SAFE_FREE(rparam);
	SAFE_FREE(rdata);
	SAFE_FREE(last_entry);

	if (res == -1) {
		errno = cli_errno(cli);
	} else {
		if (!return_cnt) {
			/* this is a very special case, when the domain master for the
			   work group isn't part of the work group itself, there is something
			   wild going on */
			errno = ENOENT;
		}
	    }

	return(return_cnt > 0);
}
Beispiel #5
0
int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32_t, const char *, void *), void *state)
{
	char *rparam = NULL;
	char *rdata = NULL;
	char *p;
	unsigned int rdrcnt,rprcnt;
	char param[1024];
	int count = -1;

	/* now send a SMBtrans command with api RNetShareEnum */
	p = param;
	SSVAL(p,0,0); /* api number */
	p += 2;
	strlcpy(p,"WrLeh",sizeof(param)-PTR_DIFF(p,param));
	p = skip_string(param,sizeof(param),p);
	strlcpy(p,"B13BWz",sizeof(param)-PTR_DIFF(p,param));
	p = skip_string(param,sizeof(param),p);
	SSVAL(p,0,1);
	/*
	 * Win2k needs a *smaller* buffer than 0xFFFF here -
	 * it returns "out of server memory" with 0xFFFF !!! JRA.
	 */
	SSVAL(p,2,0xFFE0);
	p += 4;

	if (cli_api(cli,
		    param, PTR_DIFF(p,param), 1024,  /* Param, length, maxlen */
		    NULL, 0, 0xFFE0,            /* data, length, maxlen - Win2k needs a small buffer here too ! */
		    &rparam, &rprcnt,                /* return params, length */
		    &rdata, &rdrcnt))                /* return data, length */
		{
			int res = rparam? SVAL(rparam,0) : -1;

			if (res == 0 || res == ERRmoredata) {
				int converter=SVAL(rparam,2);
				int i;
				char *rdata_end = rdata + rdrcnt;

				count=SVAL(rparam,4);
				p = rdata;

				for (i=0;i<count;i++,p+=20) {
					char *sname;
					int type;
					int comment_offset;
					const char *cmnt;
					const char *p1;
					char *s1, *s2;
					size_t len;
					TALLOC_CTX *frame = talloc_stackframe();

					if (p + 20 > rdata_end) {
						TALLOC_FREE(frame);
						break;
					}

					sname = p;
					type = SVAL(p,14);
					comment_offset = (IVAL(p,16) & 0xFFFF) - converter;
					if (comment_offset < 0 ||
							comment_offset > (int)rdrcnt) {
						TALLOC_FREE(frame);
						break;
					}
					cmnt = comment_offset?(rdata+comment_offset):"";

					/* Work out the comment length. */
					for (p1 = cmnt, len = 0; *p1 &&
							p1 < rdata_end; len++)
						p1++;
					if (!*p1) {
						len++;
					}
					pull_string_talloc(frame,rdata,0,
						&s1,sname,14,STR_ASCII);
					pull_string_talloc(frame,rdata,0,
						&s2,cmnt,len,STR_ASCII);
					if (!s1 || !s2) {
						TALLOC_FREE(frame);
						continue;
					}

					fn(s1, type, s2, state);

					TALLOC_FREE(frame);
				}
			} else {
				DEBUG(4,("NetShareEnum res=%d\n", res));
			}
		} else {
			DEBUG(4,("NetShareEnum failed\n"));
		}

	SAFE_FREE(rparam);
	SAFE_FREE(rdata);

	return count;
}
Beispiel #6
0
int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state)
{
	char *rparam = NULL;
	char *rdata = NULL;
	char *p;
	unsigned int rdrcnt,rprcnt;
	pstring param;
	int count = -1;

	/* now send a SMBtrans command with api RNetShareEnum */
	p = param;
	SSVAL(p,0,0); /* api number */
	p += 2;
	pstrcpy_base(p,"WrLeh",param);
	p = skip_string(param,sizeof(param),p);
	pstrcpy_base(p,"B13BWz",param);
	p = skip_string(param,sizeof(param),p);
	SSVAL(p,0,1);
	/*
	 * Win2k needs a *smaller* buffer than 0xFFFF here -
	 * it returns "out of server memory" with 0xFFFF !!! JRA.
	 */
	SSVAL(p,2,0xFFE0);
	p += 4;
	
	if (cli_api(cli, 
		    param, PTR_DIFF(p,param), 1024,  /* Param, length, maxlen */
		    NULL, 0, 0xFFE0,            /* data, length, maxlen - Win2k needs a small buffer here too ! */
		    &rparam, &rprcnt,                /* return params, length */
		    &rdata, &rdrcnt))                /* return data, length */
		{
			int res = rparam? SVAL(rparam,0) : -1;
			
			if (res == 0 || res == ERRmoredata) {
				int converter=SVAL(rparam,2);
				int i;
				
				count=SVAL(rparam,4);
				p = rdata;
				
				for (i=0;i<count;i++,p+=20) {
					char *sname = p;
					int type = SVAL(p,14);
					int comment_offset = IVAL(p,16) & 0xFFFF;
					const char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
					pstring s1, s2;

					pull_ascii_pstring(s1, sname);
					pull_ascii_pstring(s2, cmnt);

					fn(s1, type, s2, state);
				}
			} else {
				DEBUG(4,("NetShareEnum res=%d\n", res));
			}      
		} else {
			DEBUG(4,("NetShareEnum failed\n"));
		}
  
	SAFE_FREE(rparam);
	SAFE_FREE(rdata);
	
	return count;
}
Beispiel #7
0
/****************************************************************************
call a NetServerEnum for the specified workgroup and servertype mask.  This
function then calls the specified callback function for each name returned.

The callback function takes 4 arguments: the machine name, the server type,
the comment and a state pointer.
****************************************************************************/
BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
		       void (*fn)(const char *, uint32, const char *, void *),
		       void *state)
{
	char *rparam = NULL;
	char *rdata = NULL;
	unsigned int rdrcnt,rprcnt;
	char *p;
	pstring param;
	int uLevel = 1;
	int count = -1;

	errno = 0; /* reset */

	/* send a SMBtrans command with api NetServerEnum */
	p = param;
	SSVAL(p,0,0x68); /* api number */
	p += 2;
	pstrcpy_base(p,"WrLehDz", param);
	p = skip_string(p,1);
  
	pstrcpy_base(p,"B16BBDz", param);

	p = skip_string(p,1);
	SSVAL(p,0,uLevel);
	SSVAL(p,2,CLI_BUFFER_SIZE);
	p += 4;
	SIVAL(p,0,stype);
	p += 4;

	p += push_ascii(p, workgroup, sizeof(pstring)-PTR_DIFF(p,param)-1, STR_TERMINATE|STR_UPPER);
	
	if (cli_api(cli, 
                    param, PTR_DIFF(p,param), 8,        /* params, length, max */
                    NULL, 0, CLI_BUFFER_SIZE,               /* data, length, max */
                    &rparam, &rprcnt,                   /* return params, return size */
                    &rdata, &rdrcnt                     /* return data, return size */
                   )) {
		int res = rparam? SVAL(rparam,0) : -1;
			
		if (res == 0 || res == ERRmoredata) {
			int i;
			int converter=SVAL(rparam,2);

			count=SVAL(rparam,4);
			p = rdata;
					
			for (i = 0;i < count;i++, p += 26) {
				char *sname = p;
				int comment_offset = (IVAL(p,22) & 0xFFFF)-converter;
				const char *cmnt = comment_offset?(rdata+comment_offset):"";
				pstring s1, s2;

				if (comment_offset < 0 || comment_offset > (int)rdrcnt) continue;

				stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;

				pull_ascii_pstring(s1, sname);
				pull_ascii_pstring(s2, cmnt);
				fn(s1, stype, s2, state);
			}
		}
	}
  
	SAFE_FREE(rparam);
	SAFE_FREE(rdata);

	if (count < 0) {
	    errno = cli_errno(cli);
	} else {
	    if (!count) {
		/* this is a very special case, when the domain master for the 
		   work group isn't part of the work group itself, there is something
		   wild going on */
		errno = ENOENT;
	    }
	}
			
	return(count > 0);
}
Beispiel #8
0
int cli_print_queue(struct cli_state *cli,
		    void (*fn)(struct print_job_info *))
{
	char *rparam = NULL;
	char *rdata = NULL;
	char *p;
	unsigned int rdrcnt, rprcnt;
	char param[1024];
	int result_code=0;
	int i = -1;

	memset(param,'\0',sizeof(param));

	p = param;
	SSVAL(p,0,76);         /* API function number 76 (DosPrintJobEnum) */
	p += 2;
	strlcpy_base(p,"zWrLeh", param, sizeof(param));   /* parameter description? */
	p = skip_string(param,sizeof(param),p);
	strlcpy_base(p,"WWzWWDDzz", param, sizeof(param));  /* returned data format */
	p = skip_string(param,sizeof(param),p);
	strlcpy_base(p,cli->share, param, sizeof(param));    /* name of queue */
	p = skip_string(param,sizeof(param),p);
	SSVAL(p,0,2);   /* API function level 2, PRJINFO_2 data structure */
	SSVAL(p,2,1000); /* size of bytes of returned data buffer */
	p += 4;
	strlcpy_base(p,"", param,sizeof(param));   /* subformat */
	p = skip_string(param,sizeof(param),p);

	DEBUG(4,("doing cli_print_queue for %s\n", cli->share));

	if (cli_api(cli,
		    param, PTR_DIFF(p,param), 1024,  /* Param, length, maxlen */
		    NULL, 0, CLI_BUFFER_SIZE,            /* data, length, maxlen */
		    &rparam, &rprcnt,                /* return params, length */
		    &rdata, &rdrcnt)) {               /* return data, length */
		int converter;
		result_code = SVAL(rparam,0);
		converter = SVAL(rparam,2);       /* conversion factor */

		if (result_code == 0) {
			struct print_job_info job;

			p = rdata;

			for (i = 0; i < SVAL(rparam,4); ++i) {
				job.id = SVAL(p,0);
				job.priority = SVAL(p,2);
				fstrcpy(job.user,
					fix_char_ptr(SVAL(p,4), converter,
						     rdata, rdrcnt));
				job.t = make_unix_date3(
					p + 12, cli_state_server_time_zone(cli));
				job.size = IVAL(p,16);
				fstrcpy(job.name,fix_char_ptr(SVAL(p,24),
							      converter,
							      rdata, rdrcnt));
				fn(&job);
				p += 28;
			}
		}
	}

	/* If any parameters or data were returned, free the storage. */
	SAFE_FREE(rparam);
	SAFE_FREE(rdata);

	return i;
}