mirror of
https://github.com/samba-team/samba.git
synced 2025-02-22 05:57:43 +03:00
- moved the uid handling to uid.c
- added setfsuid() support (for Linux) - started adding some of Lukes changes, just the loadparm and ipc ones so far (This used to be commit 72543810ce3eb5ea7b141f957edf38b4c46b1ea4)
This commit is contained in:
parent
0966bf7fb7
commit
81e398963d
@ -223,6 +223,7 @@ Here come some platform specific sections
|
||||
#define USE_SETSID
|
||||
#define HAVE_BZERO
|
||||
#define HAVE_MEMMOVE
|
||||
#define USE_SETFS
|
||||
#ifdef SHADOW_PWD
|
||||
#ifndef crypt
|
||||
#define crypt pw_encrypt
|
||||
|
@ -583,6 +583,8 @@ struct from_host {
|
||||
};
|
||||
|
||||
/* and a few prototypes */
|
||||
BOOL become_guest(void);
|
||||
void init_uid(void);
|
||||
BOOL user_ok(char *user,int snum);
|
||||
int sys_rename(char *from, char *to);
|
||||
int sys_select(fd_set *fds,struct timeval *tval);
|
||||
|
@ -3585,34 +3585,6 @@ int PutUniCode(char *dst,char *src)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
pstring smbrun_path = SMBRUN;
|
||||
|
||||
/****************************************************************************
|
||||
run a command via system() using smbrun
|
||||
****************************************************************************/
|
||||
int smbrun(char *cmd,char *outfile)
|
||||
{
|
||||
int ret;
|
||||
pstring syscmd;
|
||||
|
||||
if (!file_exist(smbrun_path,NULL))
|
||||
{
|
||||
DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",smbrun_path));
|
||||
return(1);
|
||||
}
|
||||
|
||||
sprintf(syscmd,"%s \"(%s 2>&1) > %s\"",
|
||||
smbrun_path,cmd,
|
||||
outfile?outfile:"/dev/null");
|
||||
|
||||
DEBUG(5,("smbrun - running %s ",syscmd));
|
||||
ret = system(syscmd);
|
||||
DEBUG(5,("gave %d\n",ret));
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
a wrapper for gethostbyname() that tries with all lower and all upper case
|
||||
if the initial name fails
|
||||
@ -3745,8 +3717,7 @@ my own panic function - not suitable for general use
|
||||
********************************************************************/
|
||||
void ajt_panic(void)
|
||||
{
|
||||
pstring cmd = "/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT &";
|
||||
smbrun(cmd,NULL);
|
||||
system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT &");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -43,6 +43,7 @@ extern char *lp_guestaccount(int iService);
|
||||
extern char *lp_printcapname(void);
|
||||
extern char *lp_lockdir(void);
|
||||
extern char *lp_logfile(void);
|
||||
extern char *lp_smbrun(void);
|
||||
extern char *lp_configfile(void);
|
||||
extern char *lp_smb_passwd_file(void);
|
||||
extern char *lp_rootdir(void);
|
||||
@ -55,6 +56,7 @@ extern char *lp_domain_controller(void);
|
||||
extern char *lp_username_map(void);
|
||||
extern char *lp_hosts_equiv(void);
|
||||
extern char *lp_logon_script(void);
|
||||
extern char *lp_wins_server(void);
|
||||
extern char *lp_magicscript(int iService);
|
||||
extern char *lp_magicoutput(int iService);
|
||||
extern char *lp_mangled_map(int iService);
|
||||
|
@ -58,7 +58,6 @@ BOOL bLoaded = False;
|
||||
extern int DEBUGLEVEL;
|
||||
extern int ReadSize;
|
||||
extern pstring user_socket_options;
|
||||
extern pstring smbrun_path;
|
||||
|
||||
#ifndef GLOBAL_NAME
|
||||
#define GLOBAL_NAME "global"
|
||||
@ -132,6 +131,8 @@ typedef struct
|
||||
char *szUsernameMap;
|
||||
char *szCharacterSet;
|
||||
char *szLogonScript;
|
||||
char *szWINSserver;
|
||||
char *szSmbrun;
|
||||
int max_log_size;
|
||||
int mangled_stack;
|
||||
int max_xmit;
|
||||
@ -368,7 +369,7 @@ struct parm_struct
|
||||
{"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL},
|
||||
{"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
|
||||
{"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
|
||||
{"smbrun", P_GSTRING, P_GLOBAL, smbrun_path, NULL},
|
||||
{"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
|
||||
{"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL},
|
||||
{"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL},
|
||||
{"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL},
|
||||
@ -395,6 +396,7 @@ struct parm_struct
|
||||
{"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
|
||||
{"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
|
||||
{"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
|
||||
{"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
|
||||
{"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
|
||||
{"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
|
||||
{"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
|
||||
@ -543,6 +545,7 @@ static void init_globals(void)
|
||||
string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
|
||||
string_set(&Globals.szLockDir, LOCKDIR);
|
||||
string_set(&Globals.szRootdir, "/");
|
||||
string_set(&Globals.szSmbrun, SMBRUN);
|
||||
sprintf(s,"Samba %s",VERSION);
|
||||
string_set(&Globals.szServerString,s);
|
||||
Globals.bLoadPrinters = True;
|
||||
@ -677,6 +680,7 @@ char *lp_string(char *s)
|
||||
int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
|
||||
|
||||
FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
|
||||
FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
|
||||
FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
|
||||
FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
|
||||
FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
|
||||
@ -696,6 +700,7 @@ FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController)
|
||||
FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
|
||||
FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
|
||||
FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
|
||||
FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
|
||||
|
||||
FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
|
||||
FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
|
||||
|
@ -751,44 +751,64 @@ struct srv_info_struct
|
||||
filter out unwanted server info
|
||||
******************************************************************/
|
||||
static BOOL filter_server_info(struct srv_info_struct *server,
|
||||
char *domain)
|
||||
BOOL domains,
|
||||
char *domain, uint32 request)
|
||||
{
|
||||
if (*domain)
|
||||
return(strequal(domain, server->domain));
|
||||
|
||||
return (True); /* be indiscriminate: get all servers! */
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
find server in the files saved by nmbd. Return True if we find it.
|
||||
******************************************************************/
|
||||
static BOOL find_server(struct srv_info_struct *servers, int num_servers,
|
||||
char *domain, char *name)
|
||||
{
|
||||
int count;
|
||||
|
||||
if (!servers || num_servers == 0) return (False);
|
||||
|
||||
for (count = 0; count < num_servers; count++) {
|
||||
struct srv_info_struct *s;
|
||||
|
||||
s = &servers[count];
|
||||
|
||||
if (strequal(name, s->name)) {
|
||||
StrnCpy(domain, s->domain, sizeof(pstring)-1);
|
||||
return (True);
|
||||
if (*domain == 0)
|
||||
{
|
||||
if (strequal(lp_workgroup(), server->domain)) {
|
||||
return True;
|
||||
}
|
||||
else if (domains)
|
||||
{
|
||||
DEBUG(4,("primary domain:reject %8x %s %s\n",request,server->name,server->domain));
|
||||
return False;
|
||||
}
|
||||
else if ((request & SV_TYPE_DOMAIN_ENUM) &&
|
||||
(server->type & SV_TYPE_DOMAIN_ENUM))
|
||||
{
|
||||
DEBUG(4,("rej:DOM %8x: %s %s\n",server->type,server->name,server->domain));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strequal(domain, server->domain))
|
||||
{
|
||||
/*
|
||||
if (request == SV_TYPE_LOCAL_LIST_ONLY &&
|
||||
!(server->type & SV_TYPE_LOCAL_LIST_ONLY))
|
||||
{
|
||||
DEBUG(4,("rej:LOC %8x: ok %s %s\n",request,server->name,server->domain));
|
||||
return False;
|
||||
}
|
||||
*/
|
||||
if ((request == (SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM)) &&
|
||||
!(server->type&SV_TYPE_DOMAIN_ENUM))
|
||||
{
|
||||
DEBUG(4,("rej:LOCDOM %8x: ok %s %s\n",request,server->name,server->domain));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
else if (!domains)
|
||||
{
|
||||
DEBUG(4,("domain:%s %s %s\n",domain,server->name,server->domain));
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
}
|
||||
return (False);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
get server info lists from the files saved by nmbd. Return the
|
||||
number of entries
|
||||
******************************************************************/
|
||||
static int get_server_info(uint32 servertype,
|
||||
struct srv_info_struct **servers)
|
||||
struct srv_info_struct **servers, BOOL domains, char *domain)
|
||||
{
|
||||
FILE *f;
|
||||
pstring fname;
|
||||
@ -807,18 +827,23 @@ static int get_server_info(uint32 servertype,
|
||||
DEBUG(4,("Can't open %s - %s\n",fname,strerror(errno)));
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* request for everything is code for request all servers */
|
||||
if (servertype == SV_TYPE_ALL) servertype &= ~SV_TYPE_DOMAIN_ENUM;
|
||||
|
||||
DEBUG(4, ("Servertype search: %8x domains:%s\n", servertype,BOOLSTR(domains)));
|
||||
|
||||
while (!feof(f))
|
||||
{
|
||||
fstring stype;
|
||||
struct srv_info_struct *s;
|
||||
char *ptr = line;
|
||||
BOOL ok = True;
|
||||
*ptr = 0;
|
||||
|
||||
fgets(line,sizeof(line)-1,f);
|
||||
if (!*line) continue;
|
||||
|
||||
|
||||
if (count == alloced) {
|
||||
alloced += 10;
|
||||
(*servers) = (struct srv_info_struct *)
|
||||
@ -827,32 +852,52 @@ static int get_server_info(uint32 servertype,
|
||||
bzero((char *)((*servers)+count),sizeof(**servers)*(alloced-count));
|
||||
}
|
||||
s = &(*servers)[count];
|
||||
|
||||
s->server_added = True;
|
||||
|
||||
|
||||
if (!next_token(&ptr,s->name , NULL)) continue;
|
||||
if (!next_token(&ptr,stype , NULL)) continue;
|
||||
if (!next_token(&ptr,s->comment, NULL)) continue;
|
||||
if (!next_token(&ptr,s->domain , NULL)) {
|
||||
/* this allows us to cop with an old nmbd */
|
||||
/* this allows us to cope with an old nmbd */
|
||||
strcpy(s->domain,my_workgroup());
|
||||
}
|
||||
|
||||
if (sscanf(stype,"%X",&s->type) != 1) continue;
|
||||
|
||||
|
||||
if (sscanf(stype,"%X",&s->type) != 1) { DEBUG(4,("r:host file ")); ok = False; }
|
||||
|
||||
/* doesn't match up: don't want it */
|
||||
if (!(servertype & s->type)) continue;
|
||||
|
||||
/* server entry is a domain, we haven't asked for domains: don't want it */
|
||||
if ((s->type&SV_TYPE_DOMAIN_ENUM) && !(servertype&SV_TYPE_DOMAIN_ENUM))
|
||||
continue;
|
||||
|
||||
DEBUG(4,("Server %20s %8x %25s %15s\n",
|
||||
s->name, stype, s->comment, s->domain));
|
||||
|
||||
count++;
|
||||
if (!(servertype & s->type)) { DEBUG(4,("r:serv type ")); ok = False; }
|
||||
|
||||
if ((servertype == ~SV_TYPE_DOMAIN_ENUM) &&
|
||||
(s->type & SV_TYPE_DOMAIN_ENUM))
|
||||
{
|
||||
DEBUG(4,("s:all x dom "));
|
||||
ok = False;
|
||||
}
|
||||
|
||||
if (domains && !(domain && *domain && strequal(domain, s->domain)))
|
||||
{
|
||||
if (!(s->type & SV_TYPE_DOMAIN_ENUM))
|
||||
{
|
||||
DEBUG(4,("r:dom enum "));
|
||||
ok = False;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
DEBUG(4,("**SV** %20s %8x %25s %15s\n",
|
||||
s->name, s->type, s->comment, s->domain));
|
||||
|
||||
s->type |= SV_TYPE_LOCAL_LIST_ONLY;
|
||||
s->server_added = True;
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(4,("%20s %8x %25s %15s\n",
|
||||
s->name, s->type, s->comment, s->domain));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fclose(f);
|
||||
return(count);
|
||||
}
|
||||
@ -957,8 +1002,14 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data,
|
||||
int counted=0,total=0;
|
||||
int i;
|
||||
fstring domain;
|
||||
BOOL domain_request = (servertype & SV_TYPE_DOMAIN_ENUM) &&
|
||||
!(servertype == SV_TYPE_ALL);
|
||||
BOOL domains;
|
||||
BOOL domain_request;
|
||||
BOOL local_request = servertype & SV_TYPE_LOCAL_LIST_ONLY;
|
||||
|
||||
/*if (servertype == SV_TYPE_ALL) servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);*/
|
||||
if (servertype == SV_TYPE_ALL) servertype &= ~SV_TYPE_DOMAIN_ENUM;
|
||||
|
||||
domain_request = servertype & SV_TYPE_DOMAIN_ENUM;
|
||||
|
||||
domain[0] = 0;
|
||||
p += 8;
|
||||
@ -966,49 +1017,46 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data,
|
||||
if (!prefix_ok(str1,"WrLehD")) return False;
|
||||
if (!check_server_info(uLevel,str2)) return False;
|
||||
|
||||
DEBUG(4, ("server request level: %s\n", str2));
|
||||
DEBUG(4, ("server request level: %s %8x ", str2, servertype));
|
||||
DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
|
||||
DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
|
||||
|
||||
if (strcmp(str1, "WrLehDO") == 0)
|
||||
{
|
||||
/* asking for servers. we will have to work out which workgroup was
|
||||
requested, as we maintain lists for multiple workgroups */
|
||||
domains = False;
|
||||
}
|
||||
else if (strcmp(str1, "WrLehDz") == 0)
|
||||
{
|
||||
/* asking for a specific workgroup */
|
||||
domains = True;
|
||||
StrnCpy(domain, p, sizeof(fstring)-1);
|
||||
}
|
||||
|
||||
if (lp_browse_list())
|
||||
{
|
||||
total = get_server_info(servertype,&servers);
|
||||
}
|
||||
|
||||
if (!domain[0] && !domain_request) {
|
||||
extern fstring remote_machine;
|
||||
/* must be a server request with an assumed domain. find a domain */
|
||||
|
||||
if (find_server(servers, total, domain, remote_machine)) {
|
||||
DEBUG(4, ("No domain specified: using %s for %s\n",
|
||||
domain, remote_machine));
|
||||
} else {
|
||||
/* default to soemthing sensible */
|
||||
strcpy(domain,my_workgroup());
|
||||
}
|
||||
total = get_server_info(servertype,&servers,domains,domain);
|
||||
}
|
||||
|
||||
data_len = fixed_len = string_len = 0;
|
||||
|
||||
for (i=0;i<total;i++)
|
||||
if (filter_server_info(&servers[i],domain)) {
|
||||
data_len += fill_srv_info(&servers[i],uLevel,0,&f_len,0,&s_len,0);
|
||||
if (data_len <= buf_len)
|
||||
{
|
||||
counted++;
|
||||
fixed_len += f_len;
|
||||
string_len += s_len;
|
||||
}
|
||||
{
|
||||
for (i=0;i<total;i++)
|
||||
{
|
||||
struct srv_info_struct *s = &servers[i];
|
||||
if (filter_server_info(s,domains,domain,local_request|domain_request))
|
||||
{
|
||||
data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
|
||||
DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
|
||||
s->name, s->type, s->comment, s->domain));
|
||||
|
||||
if (data_len <= buf_len)
|
||||
{
|
||||
counted++;
|
||||
fixed_len += f_len;
|
||||
string_len += s_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*rdata_len = fixed_len + string_len;
|
||||
*rdata = REALLOC(*rdata,*rdata_len);
|
||||
@ -1021,10 +1069,15 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data,
|
||||
|
||||
{
|
||||
int count2 = counted;
|
||||
for (i = 0; i < total && count2;i++) {
|
||||
if (filter_server_info(&servers[i],domain)) {
|
||||
fill_srv_info(&servers[i],uLevel,&p,&f_len,&p2,&s_len,*rdata);
|
||||
count2--;
|
||||
for (i = 0; i < total && count2;i++)
|
||||
{
|
||||
struct srv_info_struct *s = &servers[i];
|
||||
if (filter_server_info(s,domains,domain,local_request|domain_request))
|
||||
{
|
||||
fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata);
|
||||
DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
|
||||
s->name, s->type, s->comment, s->domain));
|
||||
count2--;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1657,7 +1710,7 @@ static BOOL api_RNetServerGetInfo(int cnum,int uid, char *param,char *data,
|
||||
|
||||
strcpy(comment,lp_serverstring());
|
||||
|
||||
if ((count=get_server_info(SV_TYPE_ALL,&servers))>0) {
|
||||
if ((count=get_server_info(SV_TYPE_ALL,&servers,False,NULL))>0) {
|
||||
for (i=0;i<count;i++)
|
||||
if (strequal(servers[i].name,local_machine)) {
|
||||
servertype = servers[i].type;
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "reply.h"
|
||||
|
||||
pstring servicesf = CONFIGFILE;
|
||||
pstring OriginalDir ="/";
|
||||
extern pstring debugf;
|
||||
extern pstring sesssetup_user;
|
||||
|
||||
@ -34,16 +33,8 @@ char *InBuffer = NULL;
|
||||
char *OutBuffer = NULL;
|
||||
char *last_inbuf = NULL;
|
||||
|
||||
int initial_uid = 0;
|
||||
int initial_gid = 0;
|
||||
|
||||
BOOL share_mode_pending = False;
|
||||
|
||||
/* have I done a become_user? */
|
||||
static struct {
|
||||
int cnum, uid;
|
||||
} last_user;
|
||||
|
||||
/* the last message the was processed */
|
||||
int last_message = -1;
|
||||
|
||||
@ -1373,8 +1364,6 @@ int write_file(int fnum,char *data,int n)
|
||||
}
|
||||
|
||||
|
||||
static int old_umask = 022;
|
||||
|
||||
/****************************************************************************
|
||||
load parameters specific to a connection/service
|
||||
****************************************************************************/
|
||||
@ -1419,261 +1408,6 @@ BOOL become_service(int cnum,BOOL do_chdir)
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
become the specified uid
|
||||
****************************************************************************/
|
||||
static BOOL become_uid(int uid)
|
||||
{
|
||||
if (initial_uid != 0)
|
||||
return(True);
|
||||
|
||||
#ifdef AIX
|
||||
{
|
||||
/* AIX 3 stuff - inspired by a code fragment in wu-ftpd */
|
||||
priv_t priv;
|
||||
|
||||
priv.pv_priv[0] = 0;
|
||||
priv.pv_priv[1] = 0;
|
||||
if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_EFFECTIVE|PRIV_BEQUEATH,
|
||||
&priv, sizeof(priv_t)) < 0 ||
|
||||
setuidx(ID_REAL|ID_EFFECTIVE, (uid_t)uid) < 0 ||
|
||||
seteuid((uid_t)uid) < 0)
|
||||
DEBUG(1,("Can't set uid (AIX3)"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SETRES
|
||||
if (setresuid(-1,uid,-1) != 0)
|
||||
#else
|
||||
if ((seteuid(uid) != 0) &&
|
||||
(setuid(uid) != 0))
|
||||
#endif
|
||||
{
|
||||
DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n",
|
||||
uid,getuid(), geteuid()));
|
||||
if (uid > 32000)
|
||||
DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
if (((uid == -1) || (uid == 65535)) && geteuid() != uid)
|
||||
{
|
||||
DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
become the specified gid
|
||||
****************************************************************************/
|
||||
static BOOL become_gid(int gid)
|
||||
{
|
||||
if (initial_uid != 0)
|
||||
return(True);
|
||||
|
||||
#ifdef USE_SETRES
|
||||
if (setresgid(-1,gid,-1) != 0)
|
||||
#else
|
||||
if (setgid(gid) != 0)
|
||||
#endif
|
||||
{
|
||||
DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n",
|
||||
gid,getgid(),getegid()));
|
||||
if (gid > 32000)
|
||||
DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
become the specified uid and gid
|
||||
****************************************************************************/
|
||||
static BOOL become_id(int uid,int gid)
|
||||
{
|
||||
return(become_gid(gid) && become_uid(uid));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
become the guest user
|
||||
****************************************************************************/
|
||||
static BOOL become_guest(void)
|
||||
{
|
||||
BOOL ret;
|
||||
static struct passwd *pass=NULL;
|
||||
|
||||
if (initial_uid != 0)
|
||||
return(True);
|
||||
|
||||
if (!pass)
|
||||
pass = Get_Pwnam(lp_guestaccount(-1),True);
|
||||
if (!pass) return(False);
|
||||
|
||||
ret = become_id(pass->pw_uid,pass->pw_gid);
|
||||
|
||||
if (!ret)
|
||||
DEBUG(1,("Failed to become guest. Invalid guest account?\n"));
|
||||
|
||||
last_user.cnum = -2;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
check if a username is OK
|
||||
********************************************************************/
|
||||
static BOOL check_user_ok(int cnum,user_struct *vuser,int snum)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<Connections[cnum].uid_cache.entries;i++)
|
||||
if (Connections[cnum].uid_cache.list[i] == vuser->uid) return(True);
|
||||
|
||||
if (!user_ok(vuser->name,snum)) return(False);
|
||||
|
||||
i = Connections[cnum].uid_cache.entries % UID_CACHE_SIZE;
|
||||
Connections[cnum].uid_cache.list[i] = vuser->uid;
|
||||
|
||||
if (Connections[cnum].uid_cache.entries < UID_CACHE_SIZE)
|
||||
Connections[cnum].uid_cache.entries++;
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
become the user of a connection number
|
||||
****************************************************************************/
|
||||
BOOL become_user(int cnum, int uid)
|
||||
{
|
||||
int new_umask;
|
||||
user_struct *vuser;
|
||||
int snum,gid;
|
||||
int ngroups;
|
||||
gid_t *groups;
|
||||
|
||||
if (last_user.cnum == cnum && last_user.uid == uid) {
|
||||
DEBUG(4,("Skipping become_user - already user\n"));
|
||||
return(True);
|
||||
}
|
||||
|
||||
unbecome_user();
|
||||
|
||||
if (!OPEN_CNUM(cnum)) {
|
||||
DEBUG(2,("Connection %d not open\n",cnum));
|
||||
return(False);
|
||||
}
|
||||
|
||||
snum = Connections[cnum].service;
|
||||
|
||||
if (Connections[cnum].force_user ||
|
||||
lp_security() == SEC_SHARE ||
|
||||
!(vuser = get_valid_user_struct(uid)) ||
|
||||
!check_user_ok(cnum,vuser,snum)) {
|
||||
uid = Connections[cnum].uid;
|
||||
gid = Connections[cnum].gid;
|
||||
groups = Connections[cnum].groups;
|
||||
ngroups = Connections[cnum].ngroups;
|
||||
} else {
|
||||
if (!vuser) {
|
||||
DEBUG(2,("Invalid vuid used %d\n",uid));
|
||||
return(False);
|
||||
}
|
||||
uid = vuser->uid;
|
||||
if(!*lp_force_group(snum))
|
||||
gid = vuser->gid;
|
||||
else
|
||||
gid = Connections[cnum].gid;
|
||||
groups = vuser->user_groups;
|
||||
ngroups = vuser->user_ngroups;
|
||||
}
|
||||
|
||||
if (initial_uid == 0)
|
||||
{
|
||||
if (!become_gid(gid)) return(False);
|
||||
|
||||
#ifndef NO_SETGROUPS
|
||||
if (!IS_IPC(cnum)) {
|
||||
/* groups stuff added by ih/wreu */
|
||||
if (ngroups > 0)
|
||||
if (setgroups(ngroups,groups)<0)
|
||||
DEBUG(0,("setgroups call failed!\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!Connections[cnum].admin_user && !become_uid(uid))
|
||||
return(False);
|
||||
}
|
||||
|
||||
new_umask = 0777 & ~CREATE_MODE(cnum);
|
||||
old_umask = umask(new_umask);
|
||||
|
||||
last_user.cnum = cnum;
|
||||
last_user.uid = uid;
|
||||
|
||||
DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d) new_umask=0%o\n",
|
||||
getuid(),geteuid(),getgid(),getegid(),new_umask));
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
unbecome the user of a connection number
|
||||
****************************************************************************/
|
||||
BOOL unbecome_user(void )
|
||||
{
|
||||
if (last_user.cnum == -1)
|
||||
return(False);
|
||||
|
||||
ChDir(OriginalDir);
|
||||
|
||||
umask(old_umask);
|
||||
|
||||
if (initial_uid == 0)
|
||||
{
|
||||
#ifdef USE_SETRES
|
||||
setresuid(-1,getuid(),-1);
|
||||
setresgid(-1,getgid(),-1);
|
||||
#else
|
||||
if (seteuid(initial_uid) != 0)
|
||||
setuid(initial_uid);
|
||||
setgid(initial_gid);
|
||||
#endif
|
||||
}
|
||||
#ifdef NO_EID
|
||||
if (initial_uid == 0)
|
||||
DEBUG(2,("Running with no EID\n"));
|
||||
initial_uid = getuid();
|
||||
initial_gid = getgid();
|
||||
#else
|
||||
if (geteuid() != initial_uid)
|
||||
{
|
||||
DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
|
||||
initial_uid = geteuid();
|
||||
}
|
||||
if (getegid() != initial_gid)
|
||||
{
|
||||
DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
|
||||
initial_gid = getegid();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ChDir(OriginalDir) != 0)
|
||||
DEBUG(0,("%s chdir(%s) failed in unbecome_user\n",
|
||||
timestring(),OriginalDir));
|
||||
|
||||
DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
|
||||
getuid(),geteuid(),getgid(),getegid()));
|
||||
|
||||
last_user.cnum = -1;
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
find a service entry
|
||||
****************************************************************************/
|
||||
@ -3677,8 +3411,6 @@ void process(void )
|
||||
}
|
||||
#endif
|
||||
|
||||
last_user.cnum = -1;
|
||||
|
||||
while (True)
|
||||
{
|
||||
int32 len;
|
||||
@ -3922,22 +3654,7 @@ int main(int argc,char *argv[])
|
||||
|
||||
umask(0777 & ~DEF_CREATE_MASK);
|
||||
|
||||
initial_uid = geteuid();
|
||||
initial_gid = getegid();
|
||||
|
||||
if (initial_gid != 0 && initial_uid == 0)
|
||||
{
|
||||
#ifdef HPUX
|
||||
setresgid(0,0,0);
|
||||
#else
|
||||
setgid(0);
|
||||
setegid(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
initial_uid = geteuid();
|
||||
initial_gid = getegid();
|
||||
|
||||
init_uid();
|
||||
|
||||
/* this is for people who can't start the program correctly */
|
||||
while (argc > 1 && (*argv[1] != '-'))
|
||||
@ -3999,8 +3716,6 @@ int main(int argc,char *argv[])
|
||||
DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
|
||||
DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
|
||||
|
||||
GetWd(OriginalDir);
|
||||
|
||||
#ifndef NO_GETRLIMIT
|
||||
#ifdef RLIMIT_NOFILE
|
||||
{
|
||||
|
@ -44,53 +44,54 @@ static void close_fds(void)
|
||||
This is a wrapper around the system call to allow commands to run correctly
|
||||
as non root from a program which is switching between root and non-root
|
||||
|
||||
It takes one argument as argv[1] and runs it after becoming a non-root
|
||||
user
|
||||
*/
|
||||
It takes 3 arguments as uid,gid,command and runs command after
|
||||
becoming a non-root user */
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int uid,gid;
|
||||
|
||||
close_fds();
|
||||
|
||||
if (getuid() != geteuid())
|
||||
{
|
||||
int uid,gid;
|
||||
|
||||
if (getuid() == 0)
|
||||
uid = geteuid();
|
||||
else
|
||||
uid = getuid();
|
||||
|
||||
if (getgid() == 0)
|
||||
gid = getegid();
|
||||
else
|
||||
gid = getgid();
|
||||
|
||||
if (argc != 4) exit(2);
|
||||
|
||||
uid = atoi(argv[1]);
|
||||
gid = atoi(argv[2]);
|
||||
|
||||
/* first become root - we may need to do this in order to lose
|
||||
our privilages! */
|
||||
#ifdef USE_SETRES
|
||||
setresgid(0,0,0);
|
||||
setresuid(0,0,0);
|
||||
setresgid(gid,gid,gid);
|
||||
setresuid(uid,uid,uid);
|
||||
setresgid(0,0,0);
|
||||
setresuid(0,0,0);
|
||||
#else
|
||||
setuid(0);
|
||||
seteuid(0);
|
||||
setgid(gid);
|
||||
setegid(gid);
|
||||
setuid(uid);
|
||||
seteuid(uid);
|
||||
setuid(0);
|
||||
seteuid(0);
|
||||
#endif
|
||||
|
||||
if (getuid() != uid)
|
||||
return(3);
|
||||
}
|
||||
#ifdef USE_SETFS
|
||||
setfsuid(uid);
|
||||
setfsgid(gid);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SETRES
|
||||
setresgid(gid,gid,gid);
|
||||
setresuid(uid,uid,uid);
|
||||
#else
|
||||
setgid(gid);
|
||||
setegid(gid);
|
||||
setuid(uid);
|
||||
seteuid(uid);
|
||||
#endif
|
||||
|
||||
|
||||
/* paranoia :-) */
|
||||
if (getuid() != uid)
|
||||
return(3);
|
||||
|
||||
if (geteuid() != getuid())
|
||||
return(1);
|
||||
|
||||
if (argc < 2)
|
||||
return(2);
|
||||
return(4);
|
||||
|
||||
/* this is to make sure that the system() call doesn't run forever */
|
||||
alarm(30);
|
||||
|
||||
return(system(argv[1]));
|
||||
return(system(argv[3]));
|
||||
}
|
||||
|
364
source3/smbd/uid.c
Normal file
364
source3/smbd/uid.c
Normal file
@ -0,0 +1,364 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
uid/user handling
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
extern connection_struct Connections[];
|
||||
|
||||
static int initial_uid;
|
||||
static int initial_gid;
|
||||
static int old_umask = 022;
|
||||
|
||||
int current_uid;
|
||||
int current_gid;
|
||||
|
||||
static pstring OriginalDir;
|
||||
|
||||
/* have I done a become_user? */
|
||||
static struct {
|
||||
int cnum, uid;
|
||||
} last_user;
|
||||
|
||||
/****************************************************************************
|
||||
initialise the uid routines
|
||||
****************************************************************************/
|
||||
void init_uid(void)
|
||||
{
|
||||
initial_uid = current_uid = geteuid();
|
||||
initial_gid = current_gid = getegid();
|
||||
|
||||
if (initial_gid != 0 && initial_uid == 0)
|
||||
{
|
||||
#ifdef HPUX
|
||||
setresgid(0,0,0);
|
||||
#else
|
||||
setgid(0);
|
||||
setegid(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
initial_uid = geteuid();
|
||||
initial_gid = getegid();
|
||||
|
||||
last_user.cnum = -1;
|
||||
|
||||
GetWd(OriginalDir);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
become the specified uid
|
||||
****************************************************************************/
|
||||
static BOOL become_uid(int uid)
|
||||
{
|
||||
if (initial_uid != 0)
|
||||
return(True);
|
||||
|
||||
#ifdef AIX
|
||||
{
|
||||
/* AIX 3 stuff - inspired by a code fragment in wu-ftpd */
|
||||
priv_t priv;
|
||||
|
||||
priv.pv_priv[0] = 0;
|
||||
priv.pv_priv[1] = 0;
|
||||
if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_EFFECTIVE|PRIV_BEQUEATH,
|
||||
&priv, sizeof(priv_t)) < 0 ||
|
||||
setuidx(ID_REAL|ID_EFFECTIVE, (uid_t)uid) < 0 ||
|
||||
seteuid((uid_t)uid) < 0)
|
||||
DEBUG(1,("Can't set uid (AIX3)"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SETRES
|
||||
if (setresuid(-1,uid,-1) != 0)
|
||||
#elif defined(USE_SETFS)
|
||||
if (setfsuid(uid) != 0)
|
||||
#else
|
||||
if ((seteuid(uid) != 0) &&
|
||||
(setuid(uid) != 0))
|
||||
#endif
|
||||
{
|
||||
DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n",
|
||||
uid,getuid(), geteuid()));
|
||||
if (uid > 32000)
|
||||
DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
if (((uid == -1) || (uid == 65535)) && geteuid() != uid) {
|
||||
DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
current_uid = uid;
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
become the specified gid
|
||||
****************************************************************************/
|
||||
static BOOL become_gid(int gid)
|
||||
{
|
||||
if (initial_uid != 0)
|
||||
return(True);
|
||||
|
||||
#ifdef USE_SETRES
|
||||
if (setresgid(-1,gid,-1) != 0)
|
||||
#elif defined(USE_SETFS)
|
||||
if (setfsgid(gid) != 0)
|
||||
#else
|
||||
if (setgid(gid) != 0)
|
||||
#endif
|
||||
{
|
||||
DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n",
|
||||
gid,getgid(),getegid()));
|
||||
if (gid > 32000)
|
||||
DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
current_gid = gid;
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
become the specified uid and gid
|
||||
****************************************************************************/
|
||||
static BOOL become_id(int uid,int gid)
|
||||
{
|
||||
return(become_gid(gid) && become_uid(uid));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
become the guest user
|
||||
****************************************************************************/
|
||||
BOOL become_guest(void)
|
||||
{
|
||||
BOOL ret;
|
||||
static struct passwd *pass=NULL;
|
||||
|
||||
if (initial_uid != 0)
|
||||
return(True);
|
||||
|
||||
if (!pass)
|
||||
pass = Get_Pwnam(lp_guestaccount(-1),True);
|
||||
if (!pass) return(False);
|
||||
|
||||
ret = become_id(pass->pw_uid,pass->pw_gid);
|
||||
|
||||
if (!ret)
|
||||
DEBUG(1,("Failed to become guest. Invalid guest account?\n"));
|
||||
|
||||
last_user.cnum = -2;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
check if a username is OK
|
||||
********************************************************************/
|
||||
static BOOL check_user_ok(int cnum,user_struct *vuser,int snum)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<Connections[cnum].uid_cache.entries;i++)
|
||||
if (Connections[cnum].uid_cache.list[i] == vuser->uid) return(True);
|
||||
|
||||
if (!user_ok(vuser->name,snum)) return(False);
|
||||
|
||||
i = Connections[cnum].uid_cache.entries % UID_CACHE_SIZE;
|
||||
Connections[cnum].uid_cache.list[i] = vuser->uid;
|
||||
|
||||
if (Connections[cnum].uid_cache.entries < UID_CACHE_SIZE)
|
||||
Connections[cnum].uid_cache.entries++;
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
become the user of a connection number
|
||||
****************************************************************************/
|
||||
BOOL become_user(int cnum, int uid)
|
||||
{
|
||||
int new_umask;
|
||||
user_struct *vuser;
|
||||
int snum,gid;
|
||||
int ngroups;
|
||||
gid_t *groups;
|
||||
|
||||
if (last_user.cnum == cnum && last_user.uid == uid) {
|
||||
DEBUG(4,("Skipping become_user - already user\n"));
|
||||
return(True);
|
||||
}
|
||||
|
||||
unbecome_user();
|
||||
|
||||
if (!OPEN_CNUM(cnum)) {
|
||||
DEBUG(2,("Connection %d not open\n",cnum));
|
||||
return(False);
|
||||
}
|
||||
|
||||
snum = Connections[cnum].service;
|
||||
|
||||
if (Connections[cnum].force_user ||
|
||||
lp_security() == SEC_SHARE ||
|
||||
!(vuser = get_valid_user_struct(uid)) ||
|
||||
!check_user_ok(cnum,vuser,snum)) {
|
||||
uid = Connections[cnum].uid;
|
||||
gid = Connections[cnum].gid;
|
||||
groups = Connections[cnum].groups;
|
||||
ngroups = Connections[cnum].ngroups;
|
||||
} else {
|
||||
if (!vuser) {
|
||||
DEBUG(2,("Invalid vuid used %d\n",uid));
|
||||
return(False);
|
||||
}
|
||||
uid = vuser->uid;
|
||||
if(!*lp_force_group(snum))
|
||||
gid = vuser->gid;
|
||||
else
|
||||
gid = Connections[cnum].gid;
|
||||
groups = vuser->user_groups;
|
||||
ngroups = vuser->user_ngroups;
|
||||
}
|
||||
|
||||
if (initial_uid == 0)
|
||||
{
|
||||
if (!become_gid(gid)) return(False);
|
||||
|
||||
#ifndef NO_SETGROUPS
|
||||
if (!IS_IPC(cnum)) {
|
||||
/* groups stuff added by ih/wreu */
|
||||
if (ngroups > 0)
|
||||
if (setgroups(ngroups,groups)<0)
|
||||
DEBUG(0,("setgroups call failed!\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!Connections[cnum].admin_user && !become_uid(uid))
|
||||
return(False);
|
||||
}
|
||||
|
||||
new_umask = 0777 & ~CREATE_MODE(cnum);
|
||||
old_umask = umask(new_umask);
|
||||
|
||||
last_user.cnum = cnum;
|
||||
last_user.uid = uid;
|
||||
|
||||
DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d) new_umask=0%o\n",
|
||||
getuid(),geteuid(),getgid(),getegid(),new_umask));
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
unbecome the user of a connection number
|
||||
****************************************************************************/
|
||||
BOOL unbecome_user(void )
|
||||
{
|
||||
if (last_user.cnum == -1)
|
||||
return(False);
|
||||
|
||||
ChDir(OriginalDir);
|
||||
|
||||
umask(old_umask);
|
||||
|
||||
if (initial_uid == 0)
|
||||
{
|
||||
#ifdef USE_SETRES
|
||||
setresuid(-1,getuid(),-1);
|
||||
setresgid(-1,getgid(),-1);
|
||||
#elif defined(USE_SETFS)
|
||||
setfsuid(initial_uid);
|
||||
setfsgid(initial_gid);
|
||||
#else
|
||||
if (seteuid(initial_uid) != 0)
|
||||
setuid(initial_uid);
|
||||
setgid(initial_gid);
|
||||
#endif
|
||||
}
|
||||
#ifdef NO_EID
|
||||
if (initial_uid == 0)
|
||||
DEBUG(2,("Running with no EID\n"));
|
||||
initial_uid = getuid();
|
||||
initial_gid = getgid();
|
||||
#else
|
||||
if (geteuid() != initial_uid)
|
||||
{
|
||||
DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
|
||||
initial_uid = geteuid();
|
||||
}
|
||||
if (getegid() != initial_gid)
|
||||
{
|
||||
DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
|
||||
initial_gid = getegid();
|
||||
}
|
||||
#endif
|
||||
|
||||
current_uid = initial_uid;
|
||||
current_gid = initial_gid;
|
||||
|
||||
if (ChDir(OriginalDir) != 0)
|
||||
DEBUG(0,("%s chdir(%s) failed in unbecome_user\n",
|
||||
timestring(),OriginalDir));
|
||||
|
||||
DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
|
||||
getuid(),geteuid(),getgid(),getegid()));
|
||||
|
||||
last_user.cnum = -1;
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
run a command via system() using smbrun, being careful about uid/gid handling
|
||||
****************************************************************************/
|
||||
int smbrun(char *cmd,char *outfile)
|
||||
{
|
||||
int ret;
|
||||
pstring syscmd;
|
||||
char *path = lp_smbrun();
|
||||
|
||||
if (!file_exist(path,NULL))
|
||||
{
|
||||
DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",path));
|
||||
return(1);
|
||||
}
|
||||
|
||||
sprintf(syscmd,"%s %d %d \"(%s 2>&1) > %s\"",
|
||||
path,current_uid,current_gid,cmd,
|
||||
outfile?outfile:"/dev/null");
|
||||
|
||||
DEBUG(5,("smbrun - running %s ",syscmd));
|
||||
ret = system(syscmd);
|
||||
DEBUG(5,("gave %d\n",ret));
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user