diff options
Diffstat (limited to 'source/smbd/lanman.c')
-rw-r--r-- | source/smbd/lanman.c | 776 |
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(¤t_user, snum, jobid, &werr)) + if (print_job_delete(¤t_user, jobid, &werr)) errcode = NERR_Success; break; case 82: /* pause */ - if (print_job_pause(¤t_user, snum, jobid, &werr)) + if (print_job_pause(¤t_user, jobid, &werr)) errcode = NERR_Success; break; case 83: /* resume */ - if (print_job_resume(¤t_user, snum, jobid, &werr)) + if (print_job_resume(¤t_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); |