summaryrefslogtreecommitdiffstats
path: root/source/smbd/lanman.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/lanman.c')
-rw-r--r--source/smbd/lanman.c776
1 files changed, 240 insertions, 536 deletions
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index 8bfad4ab334..c0de7c9f9c4 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Inter-process communication and named pipe handling
Copyright (C) Andrew Tridgell 1992-1998
@@ -72,7 +73,8 @@ static int CopyExpanded(connection_struct *conn,
StrnCpy(buf,src,sizeof(buf)/2);
pstring_sub(buf,"%S",lp_servicename(snum));
standard_sub_conn(conn,buf,sizeof(buf));
- l = push_ascii(*dst,buf,*n-1, STR_TERMINATE);
+ StrnCpy(*dst,buf,*n-1);
+ l = strlen(*dst) + 1;
(*dst) += l;
(*n) -= l;
return l;
@@ -82,7 +84,8 @@ static int CopyAndAdvance(char** dst, char* src, int* n)
{
int l;
if (!src || !dst || !n || !(*dst)) return(0);
- l = push_ascii(*dst,src,*n, STR_TERMINATE);
+ StrnCpy(*dst,src,*n-1);
+ l = strlen(*dst) + 1;
(*dst) += l;
(*n) -= l;
return l;
@@ -216,15 +219,27 @@ static BOOL init_package(struct pack_desc* p, int count, int subcount)
return(p->errcode == NERR_Success);
}
+#ifdef HAVE_STDARG_H
static int package(struct pack_desc* p, ...)
{
+#else
+static int package(va_alist)
+va_dcl
+{
+ struct pack_desc* p;
+#endif
va_list args;
int needed=0, stringneeded;
char* str=NULL;
int is_string=0, stringused;
int32 temp;
+#ifdef HAVE_STDARG_H
va_start(args,p);
+#else
+ va_start(args);
+ p = va_arg(args,struct pack_desc *);
+#endif
if (!*p->curpos) {
if (!p->subcount)
@@ -351,7 +366,7 @@ static void PackDriverData(struct pack_desc* desc)
SIVAL(drivdata,0,sizeof drivdata); /* cb */
SIVAL(drivdata,4,1000); /* lVersion */
memset(drivdata+8,0,32); /* szDeviceName */
- push_ascii(drivdata+8,"NULL",-1, STR_TERMINATE);
+ pstrcpy(drivdata+8,"NULL");
PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
}
@@ -443,9 +458,9 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
/* the client expects localtime */
t -= TimeDiff(t);
- PACKI(desc,"W",pjobid_to_rap(snum,queue->job)); /* uJobId */
+ PACKI(desc,"W",queue->job); /* uJobId */
if (uLevel == 1) {
- PACKS(desc,"B21",queue->fs_user); /* szUserName */
+ PACKS(desc,"B21",dos_to_unix_static(queue->fs_user)); /* szUserName */
PACKS(desc,"B",""); /* pad */
PACKS(desc,"B16",""); /* szNotifyName */
PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
@@ -455,17 +470,17 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
PACKS(desc,"z",""); /* pszStatus */
PACKI(desc,"D",t); /* ulSubmitted */
PACKI(desc,"D",queue->size); /* ulSize */
- PACKS(desc,"z",queue->fs_file); /* pszComment */
+ PACKS(desc,"z",dos_to_unix_static(queue->fs_file)); /* pszComment */
}
if (uLevel == 2 || uLevel == 3 || uLevel == 4) {
PACKI(desc,"W",queue->priority); /* uPriority */
- PACKS(desc,"z",queue->fs_user); /* pszUserName */
+ PACKS(desc,"z",dos_to_unix_static(queue->fs_user)); /* pszUserName */
PACKI(desc,"W",n+1); /* uPosition */
PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */
PACKI(desc,"D",t); /* ulSubmitted */
PACKI(desc,"D",queue->size); /* ulSize */
PACKS(desc,"z","Samba"); /* pszComment */
- PACKS(desc,"z",queue->fs_file); /* pszDocument */
+ PACKS(desc,"z",dos_to_unix_static(queue->fs_file)); /* pszDocument */
if (uLevel == 3) {
PACKS(desc,"z",""); /* pszNotifyName */
PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */
@@ -558,7 +573,7 @@ static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
DEBUG(10,("snum: %d\nprinterdriver: [%s]\nlp_driverfile: [%s]\n",
snum, drivername, lp_driverfile(snum)));
- lines = file_lines_load(lp_driverfile(snum),NULL);
+ lines = file_lines_load(lp_driverfile(snum),NULL, False);
if (!lines)
{
DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),
@@ -766,7 +781,7 @@ static int get_printerdrivernumber(int snum)
char **lines = NULL;
pstring gen_line;
pstring drivername;
-
+
/*
* Check in the tdb *first* before checking the legacy
* files. This allows an NT upload to take precedence over
@@ -790,7 +805,7 @@ static int get_printerdrivernumber(int snum)
DEBUG(10,("snum: %d\nprinterdriver: [%s]\nlp_driverfile: [%s]\n",
snum, drivername, lp_driverfile(snum)));
- lines = file_lines_load(lp_driverfile(snum), NULL);
+ lines = file_lines_load(lp_driverfile(snum), NULL, False);
if (!lines)
{
DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),strerror(errno)));
@@ -863,10 +878,10 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
str3 = p + 4;
/* remove any trailing username */
- if ((p = strchr_m(QueueName,'%')))
+ if ((p = strchr(QueueName,'%')))
*p = 0;
- DEBUG(3,("api_DosPrintQGetInfo uLevel=%d name=%s\n",uLevel,QueueName));
+ DEBUG(3,("api_DosPrintQGetInfo: uLevel=%d name=%s\n",uLevel,QueueName));
/* check it's a supported varient */
if (!prefix_ok(str1,"zWrLh"))
@@ -921,9 +936,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
if (init_package(&desc,1,count)) {
desc.subcount = count;
fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status);
- }
-
- *rdata_len = desc.usedlen;
+ }
/*
* We must set the return code to ERRbuftoosmall
@@ -932,14 +945,15 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
*/
if (!mdrcnt && lp_disable_spoolss())
desc.errcode = ERRbuftoosmall;
-
+
*rdata_len = desc.usedlen;
+
*rparam_len = 6;
*rparam = REALLOC(*rparam,*rparam_len);
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,desc.neededlen);
-
+
DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
SAFE_FREE(queue);
@@ -1095,7 +1109,7 @@ static int get_server_info(uint32 servertype,
BOOL local_list_only;
int i;
- lines = file_lines_load(lock_path(SERVER_LIST), NULL);
+ lines = file_lines_load(lock_path(SERVER_LIST), NULL, False);
if (!lines) {
DEBUG(4,("Can't open %s - %s\n",lock_path(SERVER_LIST),strerror(errno)));
return(0);
@@ -1119,13 +1133,13 @@ static int get_server_info(uint32 servertype,
if (count == alloced) {
struct srv_info_struct *ts;
-
+
alloced += 10;
ts = (struct srv_info_struct *)
Realloc(*servers,sizeof(**servers)*alloced);
if (!ts) {
- DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
- return(0);
+ DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
+ return(0);
}
else *servers = ts;
memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count));
@@ -1246,15 +1260,15 @@ static int fill_srv_info(struct srv_info_struct *service,
switch (uLevel)
{
case 0:
- push_ascii(p,service->name, 15, STR_TERMINATE);
- break;
+ StrnCpy(p,service->name,15);
+ break;
case 1:
- push_ascii(p,service->name,15, STR_TERMINATE);
- SIVAL(p,18,service->type);
- SIVAL(p,22,PTR_DIFF(p2,baseaddr));
- len += CopyAndAdvance(&p2,service->comment,&l2);
- break;
+ StrnCpy(p,service->name,15);
+ SIVAL(p,18,service->type);
+ SIVAL(p,22,PTR_DIFF(p2,baseaddr));
+ len += CopyAndAdvance(&p2,service->comment,&l2);
+ break;
}
if (stringbuf)
@@ -1331,9 +1345,9 @@ static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param
DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
if (strcmp(str1, "WrLehDz") == 0) {
- pull_ascii_fstring(domain, p);
+ StrnCpy(domain, p, sizeof(fstring)-1);
} else {
- fstrcpy(domain, global_myworkgroup);
+ StrnCpy(domain, global_myworkgroup, sizeof(fstring)-1);
}
if (lp_browse_list())
@@ -1506,7 +1520,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
}
if (!baseaddr) baseaddr = p;
- push_ascii(p,lp_servicename(snum),13, STR_TERMINATE);
+ StrnCpy(p,lp_servicename(snum),13);
if (uLevel > 0)
{
@@ -1514,7 +1528,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
SCVAL(p,13,0);
type = STYPE_DISKTREE;
if (lp_print_ok(snum)) type = STYPE_PRINTQ;
- if (strequal("IPC",lp_fstype(snum))) type = STYPE_IPC;
+ if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
SSVAL(p,14,type); /* device type */
SIVAL(p,16,PTR_DIFF(p2,baseaddr));
len += CopyExpanded(conn,snum,&p2,lp_comment(snum),&l2);
@@ -1632,7 +1646,7 @@ static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,c
*rdata = REALLOC(*rdata,*rdata_len);
memset(*rdata,0,*rdata_len);
- p2 = (*rdata) + fixed_len; /* auxiliary data (strings) will go here */
+ p2 = (*rdata) + fixed_len; /* auxillery data (strings) will go here */
p = *rdata;
f_len = fixed_len;
s_len = string_len;
@@ -1654,318 +1668,6 @@ static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,c
return(True);
}
-/****************************************************************************
- Add a share
- ****************************************************************************/
-static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- fstring sharename;
- fstring comment;
- pstring pathname;
- char *command, *cmdname;
- unsigned int offset;
- int snum;
- int res = ERRunsup;
-
- /* check it's a supported varient */
- if (!prefix_ok(str1,RAP_WShareAdd_REQ)) return False;
- if (!check_share_info(uLevel,str2)) return False;
- if (uLevel != 2) return False;
-
- pull_ascii_fstring(sharename,data);
- snum = find_service(sharename);
- if (snum >= 0) { /* already exists */
- res = ERRfilexists;
- goto error_exit;
- }
-
- /* only support disk share adds */
- if (SVAL(data,14)!=STYPE_DISKTREE) return False;
-
- offset = IVAL(data, 16);
- if (offset >= mdrcnt) {
- res = ERRinvalidparam;
- goto error_exit;
- }
- pull_ascii_fstring(comment, offset? (data+offset) : "");
-
- offset = IVAL(data, 26);
- if (offset >= mdrcnt) {
- res = ERRinvalidparam;
- goto error_exit;
- }
- pull_ascii_pstring(pathname, offset? (data+offset) : "");
-
- string_replace(sharename, '"', ' ');
- string_replace(pathname, '"', ' ');
- string_replace(comment, '"', ' ');
-
- cmdname = lp_add_share_cmd();
-
- if (!cmdname || *cmdname == '\0') return False;
-
- asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
- lp_add_share_cmd(), dyn_CONFIGFILE, sharename, pathname, comment);
-
- if (command) {
- DEBUG(10,("api_RNetShareAdd: Running [%s]\n", command ));
- if ((res = smbrun(command, NULL)) != 0) {
- DEBUG(1,("api_RNetShareAdd: Running [%s] returned (%d)\n", command, res ));
- SAFE_FREE(command);
- res = ERRnoaccess;
- goto error_exit;
- } else {
- SAFE_FREE(command);
- message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
- }
- } else return False;
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,*rdata_len);
- *rdata_len = 0;
-
- return True;
-
- error_exit:
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
- *rdata_len = 0;
- SSVAL(*rparam,0,res);
- SSVAL(*rparam,2,0);
- return True;
-
-}
-
-/****************************************************************************
- view list of groups available
- ****************************************************************************/
-static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- int i;
- int errflags=0;
- int resume_context, cli_buf_size;
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
-
- GROUP_MAP *group_list;
- int num_entries;
-
- if (strcmp(str1,"WrLeh") != 0)
- return False;
-
- /* parameters
- * W-> resume context (number of users to skip)
- * r -> return parameter pointer to receive buffer
- * L -> length of receive buffer
- * e -> return parameter number of entries
- * h -> return parameter total number of users
- */
- if (strcmp("B21",str2) != 0)
- return False;
-
- /* get list of domain groups SID_DOMAIN_GRP=2 */
- if(!enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False, False)) {
- DEBUG(3,("api_RNetGroupEnum:failed to get group list"));
- return False;
- }
-
- resume_context = SVAL(p,0);
- cli_buf_size=SVAL(p+2,0);
- DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: %d\n", resume_context, cli_buf_size));
-
- *rdata_len = cli_buf_size;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- p = *rdata;
-
- for(i=resume_context; i<num_entries; i++) {
- char* name=group_list[i].nt_name;
- if( ((PTR_DIFF(p,*rdata)+21) <= *rdata_len) ) {
- /* truncate the name at 21 chars. */
- memcpy(p, name, 21);
- DEBUG(10,("adding entry %d group %s\n", i, p));
- p += 21;
- } else {
- /* set overflow error */
- DEBUG(3,("overflow on entry %d group %s\n", i, name));
- errflags=234;
- break;
- }
- }
-
- *rdata_len = PTR_DIFF(p,*rdata);
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- SSVAL(*rparam, 0, errflags);
- SSVAL(*rparam, 2, 0); /* converter word */
- SSVAL(*rparam, 4, i-resume_context); /* is this right?? */
- SSVAL(*rparam, 6, num_entries); /* is this right?? */
-
- return(True);
-}
-
-/*******************************************************************
- get groups that a user is a member of
- ******************************************************************/
-static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *UserName = skip_string(str2,1);
- char *p = skip_string(UserName,1);
- int uLevel = SVAL(p,0);
- char *p2;
- int count=0;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- /* check it's a supported varient */
- if (!strcmp(str1,"zWrLeh"))
- return False;
- switch( uLevel ) {
- case 0:
- p2 = "B21";
- break;
- default:
- return False;
- }
-
- if (strcmp(p2,str2) != 0)
- return False;
-
- *rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
-
- /* XXXX we need a real SAM database some day */
- pstrcpy(p,"Users"); p += 21; count++;
- pstrcpy(p,"Domain Users"); p += 21; count++;
- pstrcpy(p,"Guests"); p += 21; count++;
- pstrcpy(p,"Domain Guests"); p += 21; count++;
-
- *rdata_len = PTR_DIFF(p,*rdata);
-
- SSVAL(*rparam,4,count); /* is this right?? */
- SSVAL(*rparam,6,count); /* is this right?? */
-
- return(True);
-}
-
-/*******************************************************************
- get all users
- ******************************************************************/
-static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- SAM_ACCOUNT *pwd=NULL;
- int count_sent=0;
- int count_total=0;
- int errflags=0;
- int resume_context, cli_buf_size;
-
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
-
- if (strcmp(str1,"WrLeh") != 0)
- return False;
- /* parameters
- * W-> resume context (number of users to skip)
- * r -> return parameter pointer to receive buffer
- * L -> length of receive buffer
- * e -> return parameter number of entries
- * h -> return parameter total number of users
- */
-
- resume_context = SVAL(p,0);
- cli_buf_size=SVAL(p+2,0);
- DEBUG(10,("api_RNetUserEnum:resume context: %d, client buffer size: %d\n", resume_context, cli_buf_size));
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- /* check it's a supported varient */
- if (strcmp("B21",str2) != 0)
- return False;
-
- *rdata_len = cli_buf_size;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- p = *rdata;
-
- /* to get user list enumerations for NetUserEnum in B21 format */
- pdb_init_sam(&pwd);
-
- /* Open the passgrp file - not for update. */
- become_root();
- if(!pdb_setsampwent(False)) {
- DEBUG(0, ("api_RNetUserEnum:unable to open sam database.\n"));
- unbecome_root();
- return False;
- }
- errflags=NERR_Success;
-
- while ( pdb_getsampwent(pwd) ) {
- const char *name=pdb_get_username(pwd);
- if ((name) && (*(name+strlen(name)-1)!='$')) {
- count_total++;
- if(count_total>=resume_context) {
- if( ((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21) ) {
- pstrcpy(p,name);
- DEBUG(10,("api_RNetUserEnum:adding entry %d username %s\n",count_sent,p));
- p += 21;
- count_sent++;
- } else {
- /* set overflow error */
- DEBUG(10,("api_RNetUserEnum:overflow on entry %d username %s\n",count_sent,name));
- errflags=234;
- break;
- }
- }
- }
- } ;
-
- pdb_endsampwent();
- unbecome_root();
-
- pdb_free_sam(&pwd);
-
- *rdata_len = PTR_DIFF(p,*rdata);
-
- SSVAL(*rparam,0,errflags);
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,count_sent); /* is this right?? */
- SSVAL(*rparam,6,count_total); /* is this right?? */
-
- return True;
-}
-
/****************************************************************************
@@ -2030,7 +1732,7 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
fstring user;
fstring pass1,pass2;
- pull_ascii_fstring(user,p);
+ fstrcpy(user,p);
p = skip_string(p,1);
@@ -2050,41 +1752,63 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
DEBUG(3,("Set password for <%s>\n",user));
/*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
+
+ (void)map_username(user);
+
+ /*
+ * Do any UNIX username case mangling.
+ */
+ (void)Get_Pwnam( user, True);
+
+ /*
* Attempt to verify the old password against smbpasswd entries
* Win98 clients send old and new password in plaintext for this call.
*/
{
- auth_serversupplied_info *server_info = NULL;
- DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
- if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
-
- /*
- * If unix password sync was requested, attempt to change
- * the /etc/passwd database first. Return failure if this cannot
- * be done.
- *
- * This occurs before the oem change, becouse we don't want to
- * update it if chgpasswd failed.
- *
- * Conditional on lp_unix_password_sync() becouse we don't want
- * to touch the unix db unless we have admin permission.
- */
-
- if(lp_unix_password_sync() && IS_SAM_UNIX_USER(server_info->sam_account)
- && !chgpasswd(pdb_get_username(server_info->sam_account),
- pass1,pass2,False)) {
- SSVAL(*rparam,0,NERR_badpass);
- }
-
- if (change_oem_password(server_info->sam_account,pass2))
- {
- SSVAL(*rparam,0,NERR_Success);
- }
-
- free_server_info(&server_info);
- }
- data_blob_clear_free(&password);
+ fstring saved_pass2;
+ SAM_ACCOUNT *sampass = NULL;
+
+ /*
+ * Save the new password as change_oem_password overwrites it
+ * with zeros.
+ */
+
+ fstrcpy(saved_pass2, pass2);
+
+ if (check_plaintext_password(user,pass1,strlen(pass1),&sampass) &&
+ change_oem_password(sampass,pass2,False))
+ {
+ SSVAL(*rparam,0,NERR_Success);
+
+ /*
+ * If unix password sync was requested, attempt to change
+ * the /etc/passwd database also. Return failure if this cannot
+ * be done.
+ */
+
+ if(lp_unix_password_sync() && !chgpasswd(user,pass1,saved_pass2,False))
+ SSVAL(*rparam,0,NERR_badpass);
+ }
+
+ pdb_free_sam(sampass);
+ }
+
+ /*
+ * If the above failed, attempt the plaintext password change.
+ * This tests against the /etc/passwd database only.
+ */
+
+ if(SVAL(*rparam,0) != NERR_Success)
+ {
+ if (password_ok(user, pass1,strlen(pass1),NULL) &&
+ chgpasswd(user,pass1,pass2,False))
+ {
+ SSVAL(*rparam,0,NERR_Success);
+ }
}
/*
@@ -2099,17 +1823,16 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
if(SVAL(*rparam,0) != NERR_Success)
{
- SAM_ACCOUNT *hnd = NULL;
+ SAM_ACCOUNT *sampass = NULL;
- if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd) &&
- change_lanman_password(hnd,(unsigned char *)pass1,(unsigned char *)pass2))
+ if(check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &sampass) &&
+ change_lanman_password(sampass,(unsigned char *)pass1,(unsigned char *)pass2))
{
SSVAL(*rparam,0,NERR_Success);
}
- pdb_free_sam(&hnd);
+ pdb_free_sam(sampass);
}
-
memset((char *)pass1,'\0',sizeof(fstring));
memset((char *)pass2,'\0',sizeof(fstring));
@@ -2149,7 +1872,8 @@ static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *
}
p = skip_string(p,1);
- p += pull_ascii_fstring(user,p);
+ fstrcpy(user,p);
+ p = skip_string(p,1);
DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
@@ -2160,6 +1884,11 @@ static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *
(void)map_username(user);
+ /*
+ * Do any UNIX username case mangling.
+ */
+ (void)Get_Pwnam( user, True);
+
if (pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL))
{
SSVAL(*rparam,0,NERR_Success);
@@ -2181,14 +1910,11 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
char *str1 = param+2;
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
- uint32 jobid;
- int snum;
- int errcode;
+ int jobid, errcode;
extern struct current_user current_user;
WERROR werr = WERR_OK;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
- return False;
+ jobid = SVAL(p,0);
/* check it's a supported varient */
if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
@@ -2198,7 +1924,7 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
*rparam = REALLOC(*rparam,*rparam_len);
*rdata_len = 0;
- if (!print_job_exists(snum, jobid)) {
+ if (!print_job_exists(jobid)) {
errcode = NERR_JobNotFound;
goto out;
}
@@ -2207,19 +1933,19 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
switch (function) {
case 81: /* delete */
- if (print_job_delete(&current_user, snum, jobid, &werr))
+ if (print_job_delete(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
case 82: /* pause */
- if (print_job_pause(&current_user, snum, jobid, &werr))
+ if (print_job_pause(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
case 83: /* resume */
- if (print_job_resume(&current_user, snum, jobid, &werr))
+ if (print_job_resume(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
}
-
+
if (!W_ERROR_IS_OK(werr))
errcode = W_ERROR_V(werr);
@@ -2275,7 +2001,6 @@ static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid, char *param
}
if (!W_ERROR_IS_OK(werr)) errcode = W_ERROR_V(werr);
-
out:
SSVAL(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
@@ -2316,14 +2041,12 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
char *str1 = param+2;
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
- uint32 jobid;
- int snum;
+ int jobid;
int uLevel = SVAL(p,2);
int function = SVAL(p,4);
int place, errcode;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
- return False;
+ jobid = SVAL(p,0);
*rparam_len = 4;
*rparam = REALLOC(*rparam,*rparam_len);
@@ -2334,7 +2057,7 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
(!check_printjob_info(&desc,uLevel,str2)))
return(False);
- if (!print_job_exists(snum, jobid)) {
+ if (!print_job_exists(jobid)) {
errcode=NERR_JobNotFound;
goto out;
}
@@ -2346,14 +2069,14 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
/* change job place in the queue,
data gives the new place */
place = SVAL(data,0);
- if (print_job_set_place(snum, jobid, place)) {
+ if (print_job_set_place(jobid, place)) {
errcode=NERR_Success;
}
break;
case 0xb:
/* change print job name, data gives the name */
- if (print_job_set_name(snum, jobid, data)) {
+ if (print_job_set_name(jobid, data)) {
errcode=NERR_Success;
}
break;
@@ -2425,8 +2148,8 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
p = *rdata;
p2 = p + struct_len;
if (uLevel != 20) {
- srvstr_push(NULL, p,local_machine,16,
- STR_ASCII|STR_UPPER|STR_TERMINATE);
+ StrnCpy(p,local_machine,16);
+ strupper(p);
}
p += 16;
if (uLevel > 0)
@@ -2798,7 +2521,8 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
SIVALS(p,usri11_password_age,-1); /* password age */
SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
- pstrcpy(p2, vuser && vuser->homedir ? vuser->homedir : "");
+ pstrcpy(p2, lp_logon_home());
+ standard_sub_conn(conn, p2,*rdata_len-(p2 - *rdata));
p2 = skip_string(p2,1);
SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
pstrcpy(p2,"");
@@ -2834,13 +2558,15 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SSVAL(p,42,
conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
- pstrcpy(p2, vuser && vuser->homedir ? vuser->homedir : "");
+ pstrcpy(p2,lp_logon_home());
+ standard_sub_conn(conn, p2,*rdata_len-(p2 - *rdata));
p2 = skip_string(p2,1);
SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
*p2++ = 0;
SSVAL(p,52,0); /* flags */
SIVAL(p,54,PTR_DIFF(p2,*rdata)); /* script_path */
- pstrcpy(p2,vuser && vuser->logon_script ? vuser->logon_script : "");
+ pstrcpy(p2,lp_logon_script());
+ standard_sub_conn( conn, p2,*rdata_len-(p2 - *rdata));
p2 = skip_string(p2,1);
if (uLevel == 2)
{
@@ -2865,7 +2591,7 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SSVALS(p,104,-1); /* num_logons */
SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
pstrcpy(p2,"\\\\%L");
- standard_sub_conn(conn, p2,0);
+ standard_sub_conn(conn, p2,*rdata_len-(p2 - *rdata));
p2 = skip_string(p2,1);
SSVAL(p,110,49); /* country_code */
SSVAL(p,112,860); /* code page */
@@ -2879,6 +2605,56 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
return(True);
}
+/*******************************************************************
+ get groups that a user is a member of
+ ******************************************************************/
+static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *UserName = skip_string(str2,1);
+ char *p = skip_string(UserName,1);
+ int uLevel = SVAL(p,0);
+ char *p2;
+ int count=0;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"zWrLeh") != 0) return False;
+ switch( uLevel ) {
+ case 0: p2 = "B21"; break;
+ default: return False;
+ }
+ if (strcmp(p2,str2) != 0) return False;
+
+ *rdata_len = mdrcnt + 1024;
+ *rdata = REALLOC(*rdata,*rdata_len);
+
+ SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ p = *rdata;
+
+ /* XXXX we need a real SAM database some day */
+ pstrcpy(p,"Users"); p += 21; count++;
+ pstrcpy(p,"Domain Users"); p += 21; count++;
+ pstrcpy(p,"Guests"); p += 21; count++;
+ pstrcpy(p,"Domain Guests"); p += 21; count++;
+
+ *rdata_len = PTR_DIFF(p,*rdata);
+
+ SSVAL(*rparam,4,count); /* is this right?? */
+ SSVAL(*rparam,6,count); /* is this right?? */
+
+ return(True);
+}
+
+
static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
@@ -2890,12 +2666,6 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
int uLevel;
struct pack_desc desc;
char* name;
- /* With share level security vuid will always be zero.
- Don't depend on vuser being non-null !!. JRA */
- user_struct *vuser = get_valid_user_struct(vuid);
- if(vuser != NULL)
- DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid,
- vuser->user.unix_name));
uLevel = SVAL(p,0);
name = p + 2;
@@ -2939,7 +2709,15 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
}
PACKS(&desc,"z",global_myworkgroup);/* domain */
- PACKS(&desc,"z", vuser && vuser->logon_script ? vuser->logon_script :""); /* script path */
+/* JHT - By calling lp_logon_script() and standard_sub() we have */
+/* made sure all macros are fully substituted and available */
+ {
+ pstring logon_script;
+ pstrcpy(logon_script,lp_logon_script());
+ standard_sub_conn( conn, logon_script,sizeof(logon_script) );
+ PACKS(&desc,"z", logon_script); /* script path */
+ }
+/* End of JHT mods */
PACKI(&desc,"D",0x00000000); /* reserved */
}
@@ -2999,7 +2777,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
int count;
int i;
int snum;
- uint32 jobid;
+ int job;
struct pack_desc desc;
print_queue_struct *queue=NULL;
print_status_struct status;
@@ -3016,14 +2794,14 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
if (strcmp(str1,"WWrLh") != 0) return False;
if (!check_printjob_info(&desc,uLevel,str2)) return False;
- if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid))
- return False;
+ job = SVAL(p,0);
+ snum = print_job_snum(job);
if (snum < 0 || !VALID_SNUM(snum)) return(False);
count = print_queue_status(snum,&queue,&status);
for (i = 0; i < count; i++) {
- if (queue[i].job == jobid) break;
+ if (queue[i].job == job) break;
}
if (mdrcnt > 0) {
@@ -3088,7 +2866,7 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
- /* check it's a supported variant */
+ /* check it's a supported varient */
if (strcmp(str1,"zWrLeh") != 0) return False;
if (uLevel > 2) return False; /* defined only for uLevel 0,1,2 */
if (!check_printjob_info(&desc,uLevel,str2)) return False;
@@ -3441,72 +3219,6 @@ static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,
return(True);
}
-
-/****************************************************************************
- List open sessions
- ****************************************************************************/
-static BOOL api_RNetSessionEnum(connection_struct *conn,uint16 vuid, char *param, char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- struct pack_desc desc;
- struct sessionid *session_list;
- int i, num_sessions;
-
- memset((char *)&desc,'\0',sizeof(desc));
-
- uLevel = SVAL(p,0);
-
- DEBUG(3,("RNetSessionEnum uLevel=%d\n",uLevel));
- DEBUG(7,("RNetSessionEnum req string=%s\n",str1));
- DEBUG(7,("RNetSessionEnum ret string=%s\n",str2));
-
- /* check it's a supported varient */
- if (strcmp(str1,RAP_NetSessionEnum_REQ) != 0) return False;
- if (uLevel != 2 || strcmp(str2,RAP_SESSION_INFO_L2) != 0) return False;
-
- num_sessions = list_sessions(&session_list);
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- memset((char *)&desc,'\0',sizeof(desc));
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.format = str2;
- if (!init_package(&desc,num_sessions,0)) {
- return False;
- }
-
- for(i=0; i<num_sessions; i++) {
- PACKS(&desc, "z", session_list[i].remote_machine);
- PACKS(&desc, "z", session_list[i].username);
- PACKI(&desc, "W", 1); /* num conns */
- PACKI(&desc, "W", 0); /* num opens */
- PACKI(&desc, "W", 1); /* num users */
- PACKI(&desc, "D", 0); /* session time */
- PACKI(&desc, "D", 0); /* idle time */
- PACKI(&desc, "D", 0); /* flags */
- PACKS(&desc, "z", "Unknown Client"); /* client type string */
- }
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0); /* converter */
- SSVAL(*rparam,4,num_sessions); /* count */
-
- DEBUG(4,("RNetSessionEnum: errorcode %d\n",desc.errcode));
- return True;
-}
-
-
/****************************************************************************
The buffer was too small
****************************************************************************/
@@ -3554,53 +3266,54 @@ static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,cha
-const static struct
+struct
{
char *name;
int id;
BOOL (*fn)(connection_struct *,uint16,char *,char *,
int,int,char **,char **,int *,int *);
- BOOL auth_user; /* Deny anonymous access? */
+ int flags;
} api_commands[] = {
- {"RNetShareEnum", RAP_WshareEnum, api_RNetShareEnum, True},
- {"RNetShareGetInfo", RAP_WshareGetInfo, api_RNetShareGetInfo},
- {"RNetShareAdd", RAP_WshareAdd, api_RNetShareAdd},
- {"RNetSessionEnum", RAP_WsessionEnum, api_RNetSessionEnum, True},
- {"RNetServerGetInfo", RAP_WserverGetInfo, api_RNetServerGetInfo},
- {"RNetGroupEnum", RAP_WGroupEnum, api_RNetGroupEnum, True},
- {"RNetGroupGetUsers", RAP_WGroupGetUsers, api_RNetGroupGetUsers, True},
- {"RNetUserEnum", RAP_WUserEnum, api_RNetUserEnum, True},
- {"RNetUserGetInfo", RAP_WUserGetInfo, api_RNetUserGetInfo},
- {"NetUserGetGroups", RAP_WUserGetGroups, api_NetUserGetGroups},
- {"NetWkstaGetInfo", RAP_WWkstaGetInfo, api_NetWkstaGetInfo},
- {"DosPrintQEnum", RAP_WPrintQEnum, api_DosPrintQEnum, True},
- {"DosPrintQGetInfo", RAP_WPrintQGetInfo, api_DosPrintQGetInfo},
- {"WPrintQueuePause", RAP_WPrintQPause, api_WPrintQueueCtrl},
- {"WPrintQueueResume", RAP_WPrintQContinue, api_WPrintQueueCtrl},
- {"WPrintJobEnumerate",RAP_WPrintJobEnum, api_WPrintJobEnumerate},
- {"WPrintJobGetInfo", RAP_WPrintJobGetInfo, api_WPrintJobGetInfo},
- {"RDosPrintJobDel", RAP_WPrintJobDel, api_RDosPrintJobDel},
- {"RDosPrintJobPause", RAP_WPrintJobPause, api_RDosPrintJobDel},
- {"RDosPrintJobResume",RAP_WPrintJobContinue, api_RDosPrintJobDel},
- {"WPrintDestEnum", RAP_WPrintDestEnum, api_WPrintDestEnum},
- {"WPrintDestGetInfo", RAP_WPrintDestGetInfo, api_WPrintDestGetInfo},
- {"NetRemoteTOD", RAP_NetRemoteTOD, api_NetRemoteTOD},
- {"WPrintQueuePurge", RAP_WPrintQPurge, api_WPrintQueueCtrl},
- {"NetServerEnum", RAP_NetServerEnum2, api_RNetServerEnum}, /* anon OK */
- {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms},
- {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword},
- {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon},
- {"PrintJobInfo", RAP_WPrintJobSetInfo, api_PrintJobInfo},
- {"WPrintDriverEnum", RAP_WPrintDriverEnum, api_WPrintDriverEnum},
- {"WPrintQProcEnum", RAP_WPrintQProcessorEnum,api_WPrintQProcEnum},
- {"WPrintPortEnum", RAP_WPrintPortEnum, api_WPrintPortEnum},
- {"SamOEMChangePassword",RAP_SamOEMChgPasswordUser2_P,api_SamOEMChangePassword}, /* anon OK */
- {NULL, -1, api_Unsupported}};
-
-/* The following RAP calls are not implemented by Samba:
-
- RAP_WFileEnum2 - anon not OK
-*/
+ {"RNetShareEnum", RAP_WshareEnum, api_RNetShareEnum,0},
+ {"RNetShareGetInfo", RAP_WshareGetInfo, api_RNetShareGetInfo,0},
+#if 0 /* Not yet implemented. */
+ {"RNetShareAdd", RAP_WshareAdd, api_RNetShareAdd,0},
+#endif
+ {"RNetServerGetInfo", RAP_WserverGetInfo, api_RNetServerGetInfo,0},
+#if 0 /* Not yet implemented. */
+ {"RNetGroupEnum", RAP_WGroupEnum, api_RNetGroupEnum,0},
+#endif
+ {"RNetGroupGetUsers", RAP_WGroupGetUsers, api_RNetGroupGetUsers,0},
+#if 0 /* Not yet implemented. */
+ {"RNetUserEnum", RAP_WUserEnum, api_RNetUserEnum,0},
+#endif
+ {"RNetUserGetInfo", RAP_WUserGetInfo, api_RNetUserGetInfo,0},
+ {"NetUserGetGroups", RAP_WUserGetGroups, api_NetUserGetGroups,0},
+ {"NetWkstaGetInfo", RAP_WWkstaGetInfo, api_NetWkstaGetInfo,0},
+ {"DosPrintQEnum", RAP_WPrintQEnum, api_DosPrintQEnum,0},
+ {"DosPrintQGetInfo", RAP_WPrintQGetInfo, api_DosPrintQGetInfo,0},
+ {"WPrintQueuePause", RAP_WPrintQPause, api_WPrintQueueCtrl,0},
+ {"WPrintQueueResume", RAP_WPrintQContinue, api_WPrintQueueCtrl,0},
+ {"WPrintJobEnumerate",RAP_WPrintJobEnum, api_WPrintJobEnumerate,0},
+ {"WPrintJobGetInfo", RAP_WPrintJobGetInfo, api_WPrintJobGetInfo,0},
+ {"RDosPrintJobDel", RAP_WPrintJobDel, api_RDosPrintJobDel,0},
+ {"RDosPrintJobPause", RAP_WPrintJobPause, api_RDosPrintJobDel,0},
+ {"RDosPrintJobResume",RAP_WPrintJobContinue, api_RDosPrintJobDel,0},
+ {"WPrintDestEnum", RAP_WPrintDestEnum, api_WPrintDestEnum,0},
+ {"WPrintDestGetInfo", RAP_WPrintDestGetInfo, api_WPrintDestGetInfo,0},
+ {"NetRemoteTOD", RAP_NetRemoteTOD, api_NetRemoteTOD,0},
+ {"WPrintQueuePurge", RAP_WPrintQPurge, api_WPrintQueueCtrl,0},
+ {"NetServerEnum", RAP_NetServerEnum2, api_RNetServerEnum,0},
+ {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms,0},
+ {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword,0},
+ {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon,0},
+ {"PrintJobInfo", RAP_WPrintJobSetInfo, api_PrintJobInfo,0},
+ {"WPrintDriverEnum", RAP_WPrintDriverEnum, api_WPrintDriverEnum,0},
+ {"WPrintQProcEnum", RAP_WPrintQProcessorEnum,api_WPrintQProcEnum,0},
+ {"WPrintPortEnum", RAP_WPrintPortEnum, api_WPrintPortEnum,0},
+ {"SamOEMChangePassword",RAP_SamOEMChgPasswordUser2_P,api_SamOEMChangePassword,0},
+ {NULL, -1, api_Unsupported,0}};
+
/****************************************************************************
Handle remote api calls
@@ -3637,15 +3350,6 @@ int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *
}
}
- /* Check whether this api call can be done anonymously */
-
- if (api_commands[i].auth_user && lp_restrict_anonymous()) {
- user_struct *user = get_valid_user_struct(vuid);
-
- if (!user || user->guest)
- return ERROR_NT(NT_STATUS_ACCESS_DENIED);
- }
-
rdata = (char *)malloc(1024);
if (rdata)
memset(rdata,'\0',1024);