#include #include #include #include #include #include #include "internal.h" #include "samba.m" const char subsys_samba[]="smb"; MODULE_DEFINE_VERSION(samba); static CONFIG_FILE f_smbpasswd ("/etc/smbpasswd",help_nil ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,"root","root",0600 ,subsys_samba); PUBLIC MODULE_SAMBA::MODULE_SAMBA() : LINUXCONF_MODULE("samba") { linuxconf_loadmsg ("samba",PACKAGE_REV); } static const char *keymenu=NULL; static const char *menu_status = NULL; PUBLIC void MODULE_SAMBA::setmenu ( DIALOG &dia, MENU_CONTEXT context) { if (context == MENU_NETWORK_SERVER){ keymenu = MSG_U(M_SAMBA,"Samba file server"); dia.new_menuitem ("samba","",keymenu); }else if (context == MENU_SYS_STATUS){ menu_status = MSG_U(M_SAMBASTATUS,"Samba server status"); dia.new_menuitem ("samba","",menu_status); } } PUBLIC int MODULE_SAMBA::domenu ( MENU_CONTEXT context, const char *key) { if (context == MENU_NETWORK_SERVER){ if (key == keymenu){ samba_edit(); } }else if (context == MENU_SYS_STATUS){ if (key == menu_status){ samba_status(); } } return 0; } int samba_execsmbpasswd(const char *args) { int ret = -1; const char smbpasswd[]="smbpasswd"; POPEN pop (smbpasswd,args); if (pop.isok()){ SSTRING notice; while (pop.wait(1)>=0){ char buf[100]; if (pop.readout (buf,sizeof(buf)-1) == 0){ notice.appendf ("%s\n",buf); } if (pop.readerr (buf,sizeof(buf)-1) == 0){ xconf_error ("%s: %s",smbpasswd,buf); } } ret = pop.getstatus(); // This notice message was annoying. // if (!notice.is_empty()) xconf_notice ("%s: %s",smbpasswd,notice.get()); } return ret; } /* Execute the smbpasswd command */ static void samba_smbpasswd ( bool updpassword, // Are we updating the password or simply // managing the account const char *domain, const char *args) { SMB_CONF smb; if (strcmp(domain,"/")==0 && smb.syncpass > 0 && f_smbpasswd.exist()){ // Originally syncpass was a boolean (0 or 1). 1 meaned that // we had to manage the smbpasswd file and update the password. // Now 2 means that we should not fiddle with the password // This happens when pam_smbpass is installed. The admin // want to maintain a single password database (/etc/smbpasswd). // In this case, the normal unix password is not used anymore. // We want to make sure that all utilities are dealing with the // same password database, including linuxconf. So even // /etc/pam.d/linuxconf is updated to use pam_smbpass if (!updpassword || smb.syncpass == 1){ samba_execsmbpasswd (args); } } } /* Set the samba password for a user */ void samba_setpassword( const char *user, const char *new_passwd) // If null, the account is disabled { if (!f_smbpasswd.exist()) f_smbpasswd.create(); char buf[200]; if (new_passwd == NULL){ snprintf (buf,sizeof(buf)-1,"-d %s",user); }else{ snprintf (buf,sizeof(buf)-1,"-a %s \"%s\"",user,new_passwd); } samba_smbpasswd (true,"/",buf); } PUBLIC int MODULE_SAMBA::message (const char *msg, int argc, const char *argv[]) { int ret = LNCF_NOT_APPLICABLE; if (strcmp(msg,"chgpasswd")==0){ const char *user = argv[0]; const char *passwd = argv[1]; if (!f_smbpasswd.exist()) f_smbpasswd.create(); char buf[200]; if (passwd == NULL){ snprintf (buf,sizeof(buf)-1,"-a -n %s",user); }else{ snprintf (buf,sizeof(buf)-1,"-a %s \"%s\"",user,passwd); } samba_smbpasswd (true,argv[3],buf); ret = 0; }else if (strcmp(msg,"deluser")==0){ if (strcmp(argv[1],"/")==0){ FILE_CFG *fin = f_smbpasswd.fopen ("r"); if (fin != NULL){ char path[PATH_MAX]; const char *smbpath = f_smbpasswd.getpath(); snprintf (path,sizeof(path)-1,"%s-NEW",smbpath); FILE_CFG *fout = f_smbpasswd.fopen (path,"w"); if (fout != NULL){ char buf[2000]; const char *user = argv[0]; int userlen = strlen(user); while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ if (strncmp(buf,user,userlen)!=0 || buf[userlen] != ':'){ fputs (buf,fout); } } fclose (fout); rename (path,smbpath); } fclose (fin); } } ret = 0; }else if (strcmp(msg,"disable-account")==0){ char buf[200]; snprintf (buf,sizeof(buf)-1,"-d %s",argv[0]); samba_smbpasswd (false,argv[1],buf); ret = 0; }else if (strcmp(msg,"enable-account")==0){ char buf[200]; snprintf (buf,sizeof(buf)-1,"-e %s",argv[0]); samba_smbpasswd (false,argv[1],buf); ret = 0; }else if (strcmp(msg,"newuser")==0){ char buf[200]; snprintf (buf,sizeof(buf)-1,"-a -n %s",argv[0]); samba_smbpasswd (false,argv[1],buf); ret = 0; } return ret; } static void usage () { xconf_error (MSG_U(N_SAMBAUSAGE ,"Module samba\n" "linuxconf --modulemain samba [ specific options ]\n" "\n" " without argument start the interactive mode\n" "\n") ); } PUBLIC void MODULE_SAMBA::usage (SSTRINGS &tb) { tb.add (new SSTRING (MSG_R(N_SAMBAUSAGE))); } PUBLIC int MODULE_SAMBA::execmain (int argc , char *argv[], bool) { int ret = LNCF_NOT_APPLICABLE; const char *pt = strrchr(argv[0],'/'); if (pt != NULL){ pt++; }else{ pt = argv[0]; } if (strcmp(pt,"sambaconf")==0 || strcmp(pt,"samba")==0){ ret = -1; if (argc != 1){ ::usage(); }else if (netconf_mainaccess()){ samba_edit (); ret = 0; } } return ret; } static MODULE_SAMBA samba;