#include #include #include #include "nt2linux.h" #include "nt2linux.m" #include "userconf.h" enum BACKUP_COMMAND { BACKUP_DONE, BACKUP_NOTDONE}; static int group_backup (const char *fname, BACKUP_COMMAND &done) { done = BACKUP_NOTDONE; int ret = -1; SSTRING bk; bk.setfromf ("%s.original",fname); if (!file_exist (bk.get())){ ret = file_copy (fname,bk.get()); done = BACKUP_DONE; }else{ DIALOG dia; char sel = 0; dia.newf_radio ("",sel,0,MSG_U(I_REPLACE,"Replace the old backup")); dia.newf_radio ("",sel,1,MSG_U(I_NOREPLACE,"Do not produce a backup")); dia.newf_radio ("",sel,2,MSG_U(I_NOPROCESS,"Do not do anything")); SSTRING intro; intro.setfromf(MSG_U(I_BACKUP ,"We want to backup file %s to %s\n" "but file %s already exist, do you want to") ,fname,bk.get(),bk.get()); int nof = 0; if (dia.edit (MSG_U(T_BACKUP,"Confirm backup replacement") ,intro.get() ,help_nil,nof)==MENU_ACCEPT){ ret = 0; if (sel == 0){ ret = file_copy (fname,bk.get()); done = BACKUP_DONE; } } } return ret; } static void group_confirm (const char *fname, BACKUP_COMMAND done) { if (done == BACKUP_DONE){ xconf_notice (MSG_U(N_UPDWITHBK ,"File %s has been updated\n" "and a backup copy was done in %s.original") ,fname,fname); }else{ xconf_notice (MSG_U(N_UPDWITHOUTBK ,"File %s has been updated, no backup was produced") ,fname); } } static void group_split (const char *desc, SSTRINGS &tb, int minvals) { char tmp[strlen(desc)+1]; while (*desc != '\0'){ char *dst = tmp; if (*desc == '"'){ desc++; while (*desc != '\0' && *desc != '"') *dst++ = *desc++; if (*desc == '"') desc++; }else{ while (*desc != '\0' && *desc != ',') *dst++ = *desc++; } *dst = '\0'; if (*desc == ',') desc++; tb.add (new SSTRING(tmp)); } while (tb.getnb() < minvals) tb.add (new SSTRING); } /* Turn to lower case and replace spaces with _ */ static void group_munge (char *dst, const char *src) { while (*src != '\0'){ if (*src == ' '){ *dst = '_'; }else{ *dst = tolower(*src); } dst++; src++; } } /* Convert a DOS path (e:\xx\yy) into a unix path The drive letter become a sub-directory */ static void group_cnvpath ( NT_PARMS &parms, const char *dospath, char path[PATH_MAX]) { parms.dataroot.copy (path); char *dst = path + strlen(path); *dst++ = '/'; if (isalpha(dospath[0]) && dospath[1] == ':'){ *dst++ = tolower(dospath[0]); dospath+=2; } while (*dospath != '\0'){ if (*dospath == '\\'){ *dst++ = '/'; }else{ *dst++ = tolower (*dospath); } dospath++; } *dst = '\0'; } #if 0 static void group_patch (GROUPS &grs) { // GROUPS::GROUPS should accept a CONFIG_FILE. For now, we clear // the object and reload it from /var/run/group if available if (file_exist ("/var/run/group")){ grs.remove_all(); FILE *fin = fopen ("/var/run/group","r"); if (fin != NULL){ char line[10000]; while (fgets_cont(line,sizeof(line)-1,fin)!=-1){ strip_end (line); if (line[0] != '\0'){ GROUP *ng = new GROUP(line); grs.add (ng); } } fclose (fin); } } } #endif void groups_create (SUBJECTS &info) { BACKUP_COMMAND done; if (group_backup("/etc/group",done)==-1) return; GROUPS groups; //group_patch (groups); for (int i=0; iname.get(),-1); GROUP *gr = groups.getfromgid(gid); if (gr != NULL){ SUBJECTS *ss = &s->values; for (int j=0; jgetnb(); j++){ SUBJECT *member = ss->getitem(j); const char *name = member->name.get(); if (info.locate (name)!=NULL){ // THe member is itself a group SSTRING tmp; tmp.setfromf("@%s",name); gr->addmember (tmp.get()); }else{ gr->addmember (name); } } } } CONFIG_FILE f_tmp ("/etc/group",help_nil ,CONFIGF_OPTIONAL|CONFIGF_TMPLOCK ,"root","root",0644); if (groups.write (NULL,f_tmp)!=-1){ group_confirm ("/etc/group",done); } } void groups_createldif (SUBJECTS &info) { FILE *fout = fopen ("/tmp/groups.ldif","w"); if (fout != NULL){ for (int i=0; idesc.get(),tb,3); int gid = tb.getitem(2)->getval(); if (gid != 0){ fprintf (fout,"dn: cn=%s, ou=people, dc=hdsj, dc=st-jerome, dc=qc, dc=ca\n",s->name.get()); fprintf (fout,"ntuid: %s\n",s->name.get()); fprintf (fout,"cn: %s\n",s->name.get()); fprintf (fout,"rid: %d\n",gid); SUBJECTS *ss = &s->values; for (int j=0; jgetnb(); j++){ SUBJECT *member = ss->getitem(j); const char *name = member->name.get(); fprintf (fout,"member: %s\n",name); #if 0 if (info.locate (name)!=NULL){ // THe member is itself a group SSTRING tmp; tmp.setfromf("@%s",name); gr->addmember (tmp.get()); }else{ gr->addmember (name); } #endif } if (tb.getitem(0)->is_filled()){ fprintf (fout,"description: %s\n",tb.getitem(0)->get()); } fprintf (fout,"objectclass: sambaGroup\n"); fprintf (fout,"\n"); } } fclose (fout); } } void users_create (SUBJECTS &info) { BACKUP_COMMAND done_passwd,done_shadow,done_smbpasswd,done_group; if (group_backup ("/etc/passwd",done_passwd)==-1 || group_backup ("/etc/shadow",done_shadow) ==-1 || group_backup ("/etc/group",done_group)==-1) return; if (file_exist("/etc/smbpasswd")){ if (group_backup ("/etc/smbpasswd",done_smbpasswd)==-1){ return; } } CONFIG_FILE f_passwd ("/etc/passwd",help_nil ,CONFIGF_OPTIONAL|CONFIGF_TMPLOCK); CONFIG_FILE f_shadow ("/etc/shadow",help_nil ,CONFIGF_OPTIONAL|CONFIGF_TMPLOCK ,"root","root",0600); CONFIG_FILE f_smbpasswd ("/etc/smbpasswd",help_nil ,CONFIGF_OPTIONAL ,"root","root",0600); USERS users (f_passwd,f_shadow,"/","/home","/",1000); GROUPS groups; // group_patch (groups); FILE_CFG *fsmb = f_smbpasswd.fopen ("a"); time_t ti = time(NULL); SSTRING ignored,added; for (int i=0; iname.get(); USER *u = users.getitem (name); if (u != NULL){ ignored.appendf ("%s\n",name); }else{ SSTRINGS tb; group_split (s->desc.get(),tb,4); int uid = users.getnewuid(); int gid = groups.create (name,-1); SSTRING home; home.setfromf ("/home/%s",name); u = new USER (name,"x",uid,gid ,tb.getitem(0)->get(),home.get(),"/bin/sh"); users.add (u); SHADOW *sha = new SHADOW; sha->setname(name); sha->setpasswd ("x"); users.addshadow (sha); fprintf (fsmb,"%s:%d:%s:%s:[%-13s]:LCT-%8lx:\n" ,name,uid,tb.getitem(2)->get(),tb.getitem(3)->get() ,"U",ti); added.appendf ("%s\n",name); } } CONFIG_FILE f_tmp ("/etc/group",help_nil ,CONFIGF_OPTIONAL|CONFIGF_TMPLOCK ,"root","root",0644); if (groups.write (NULL,f_tmp)!=-1 && users.write(NULL)!=-1 && f_smbpasswd.fclose (fsmb)!=-1){ xconf_notice (MSG_U(N_UPDPASSWD ,"passwd, shadow, group and smbpasswd files were updated\n" "\n" "Account added:\n%s\n" "Account not added (already exist):\n%s") ,added.get(),ignored.get()); } } void shares_create (SUBJECTS &info, SUBJECTS &groups, NT_PARMS &parms) { BACKUP_COMMAND done; if (group_backup ("/etc/smb.conf",done)==-1) return; FILE *fout = fopen ("/etc/smb.conf","a"); for (int i=0; iname.get(); SSTRINGS tb; group_split (s->desc.get(),tb,3); fprintf (fout,"[%s]\n",name); fprintf (fout,"\tavailable=yes\n"); int last = strlen(name)-1; fprintf (fout,"\tbrowsable = %s\n" ,(last >= 0 && name[last] == '$') ? "no" : "yes"); if (tb.getitem(0)->cmp("Folder")==0){ fprintf (fout,"\tcomment=%s\n",tb.getitem(2)->get()); char path[PATH_MAX]; group_cnvpath (parms,tb.getitem(1)->get(),path); fprintf (fout,"\tpath = %s\n",path); }else{ // This is a printer share fprintf (fout,"\tpath = /var/spool/lpd/%s\n",name); fprintf (fout,"\tprintable = yes\n"); fprintf (fout,"\twritable = no\n"); fprintf (fout,"\tprinter = %s\n",tb.getitem(2)->get()); // fprintf (fout,"\tprinter driver = \n"); } // Generate the write and read list from the acls SUBJECTS *acls = &s->values; SSTRING read,write,valid; for (int j=0; jgetnb(); j++){ SUBJECT *acl = acls->getitem(j); SSTRINGS tba; group_split (acl->desc.get(),tba,2); SSTRING *str = tba.getitem(1)->strchr('W')!=NULL ? &write : &read; const char *aclname = acl->name.get(); if (groups.locate(aclname) != NULL){ str->appendf (" @%s",aclname); valid.appendf (" @%s",aclname); }else{ str->appendf (" %s",aclname); valid.appendf (" %s",aclname); } } if (!valid.is_empty()){ fprintf (fout,"\tvalid users =%s\n",valid.get()); } if (!read.is_empty()) fprintf (fout,"\tread list =%s\n",read.get()); if (!write.is_empty()){ fprintf (fout,"\twritable = no\n"); fprintf (fout,"\twrite list =%s\n",write.get()); } } if (fclose (fout)!=-1){ group_confirm ("/etc/smb.conf",done); } } void printers_create (SUBJECTS &info) { BACKUP_COMMAND done; if (group_backup ("/etc/printcap",done)==-1) return; FILE *fout = fopen ("/etc/printcap","a"); for (int i=0; iname.get(); SSTRINGS tb; group_split (s->desc.get(),tb,3); char tmpname[strlen(name)+1]; group_munge (tmpname,name); fprintf (fout,"%s:\\\n",name); fprintf (fout,"\t:sd=/var/spool/lpd/%s:\\\n",name); fprintf (fout,"\t:sh:\\\n"); fprintf (fout,"\t:mx#0\\\n"); fprintf (fout,"\t:rm=%s:\\\n",name); fprintf (fout,"\t:rp=%s:\\\n",name); fprintf (fout,"\t:if=/var/spool/lpd/%s/filter:\n",name); } if (fclose (fout)!=-1){ group_confirm ("/etc/printcap",done); } } void data_create (SUBJECTS &info, SUBJECTS &groups, NT_PARMS &parms) { CONFIG_FILE f_conf ("/var/run/data.acl.sh",help_nil,CONFIGF_OPTIONAL ,"root","root",0600); FILE_CFG *fout = f_conf.fopen ("w"); fprintf (fout,"#!/bin/sh\n"); for (int i=0; iname.get(); SSTRINGS tb; group_split (s->desc.get(),tb,3); char path[PATH_MAX]; group_cnvpath (parms,name,path); SUBJECTS *acls = &s->values; // Reset the ACLs of this path fprintf (fout,"setfacl -b %s\n",path); for (int j=0; jgetnb(); j++){ SUBJECT *acl = acls->getitem(j); SSTRINGS tba; group_split (acl->desc.get(),tba,2); const char *perm = tba.getitem(1)->get(); char permbits[4]; permbits[0] = '\0'; if (strchr(perm,'R')!=NULL) strcat (permbits,"r"); if (strchr(perm,'W')!=NULL) strcat (permbits,"w"); if (strchr(perm,'X')!=NULL) strcat (permbits,"x"); const char *aclname = acl->name.get(); if (groups.locate(aclname) != NULL){ fprintf (fout,"setfacl -m g:%s:+%s %s\n" ,aclname,permbits,path); }else{ fprintf (fout,"setfacl -m u:%s:+%s %s\n" ,aclname,permbits,path); } } } if (fclose (fout)!=-1){ xconf_notice (MSG_U(N_CREATEACL ,"/var/run/data.acl.sh has been created")); } }