#include #include #include #include #include "internal.h" #include "userconf.h" #include "../paths.h" #include #include "userconf.m" #include #include "usercomng.h" static USERCONF_HELP_FILE help_group ("group"); static USERCONF_HELP_FILE help_homebase ("homebase"); PUBLIC void GROUP::setgid(int _gid) { gid = _gid; } PRIVATE void GROUP::settbmem (char **members) { tbmem.remove_all(); if (members != NULL){ int i=0; while (members[i] != NULL){ tbmem.add (new SSTRING(members[i])); i++; } } } PRIVATE void GROUP::settbmem (const SSTRINGS &members) { tbmem.remove_all(); tbmem.append (members); } PRIVATE void GROUP::init( const char *_name, const char *_passwd, int _gid) { priv = NULL; name.setfrom (_name); passwd.setfrom(_passwd); gid = _gid; } PUBLIC GROUP::GROUP( const char *_name, const char *_passwd, int _gid, char **members) { init (_name,_passwd,_gid); settbmem (members); } PUBLIC GROUP::GROUP( const char *_name, const char *_passwd, int _gid, const SSTRINGS &members) { init (_name,_passwd,_gid); settbmem (members); } PUBLIC GROUP::GROUP() { init ("","",-1); } PUBLIC GROUP::GROUP(const char *line) { // We split the line in four. The end of the line is // the list of group members which may be very long // str_splitline will pick the first 3 fields char tb[16][100]; str_splitline (line,':',tb,3); init (tb[0],tb[1],atoi(tb[2])); line = strrchr(line,':'); if (line != NULL){ str_splitline (line+1,',',tbmem); } } PUBLIC GROUP::~GROUP() { } /* Write one record of /etc/passwd */ PUBLIC void GROUP::write(FILE_CFG *fout) { fprintf (fout,"%s:%s:%d:",name.get(),passwd.get(),gid); const char *sep = ""; int nb = tbmem.getnb(); // int len = 0; for (int i=0; iget(); #if 0 if (len > 80){ fputs ("\\\n",fout); len = 0; } #endif fputs (sep,fout); fputs (member,fout); sep = ","; // len += strlen(member)+1; } fputc ('\n',fout); } PUBLIC const char *GROUP::getname() { return name.get(); } PUBLIC int GROUP::getgid() { return gid; } PUBLIC const SSTRINGS *GROUP::getmembers() { return &tbmem; } /* Check if a group is correctly configured. Return -1 if not. */ PRIVATE int GROUP::check( USERS &users, GROUPS &groups, GROUP *realone) { SSTRING status; GROUP *other = groups.getitem(name.get()); if (other != NULL && other != realone){ status.append(MSG_U(E_GROUPEXIST,"Group already exist\n")); } other = groups.getfromgid(gid); if (other != NULL && other != realone){ status.append(MSG_U(E_GROUPEXISTID ,"Group already exist (Group ID)\n")); } int nb = tbmem.getnb(); for (int i=0; iget(); if (user[0] == '@'){ if (groups.getitem(user+1)==NULL){ status.appendf(MSG_U(E_UNKNOWNGMEMBER,"Unknown member group %s\n"),user); } }else if (users.getitem(user)==NULL){ char nisuser[strlen(user)+2]; nisuser[0] = '+'; strcpy(nisuser+1,user); if (users.getitem(nisuser)==NULL){ status.appendf(MSG_U(E_UNKNOWNMEMBER ,"Unknown member user %s\n"),user); } } } int ret = 0; if (!status.is_empty()){ xconf_error ("%s",status.get()); ret = -1; } return ret; } /* Split the input lines into one string per member */ static int group_parsemem (const SSTRINGS &lines, SSTRINGS &members) { for (int i=0; iget(); while (str[0] != '\0'){ str = str_skip(str); char member[200]; str = str_copyword (member,str,sizeof(member)-1); if (member[0] != '\0'){ members.add (new SSTRING(member)); } } } return members.getnb(); } const char K_CREATEHOME[]="createhome"; const char K_CREATEPERM[]="createperm"; const char K_HOMEBASE[]="homebase"; /* Check and create the home base directory if needed */ static int group_checkhomebase(const char *base) { int ret = 0; if (base[0] != '\0' && file_type(base) == -1){ ret = -1; char buf[1000]; snprintf (buf,sizeof(buf)-1,MSG_U(Q_MISSBASE ,"Home base %s does not exist\n" "Do you want to create it"),base); if (dialog_yesno(MSG_U(T_MISSBASE,"Missing home base"),buf ,help_homebase)==MENU_YES){ ret = file_mkdir (base,0,0,0755,NULL); } } return ret; } /* Make sure the user did not entered : in the alt members lines Return -1 if any error */ static int group_checklexmembers(SSTRINGS &lines, int &noline) { int ret = 0; for (int i=0; istrchr(':')!=NULL){ noline = i; ret = -1; break; } } return ret; } /* Edit the specification of a user. Return -1 if the user escape without accepting the changes. Return 0 if the record was changed Return 1 if the record must be deleted */ PUBLIC int GROUP::edit(USERS &users, GROUPS &groups) { bool is_new = gid == -1; USERACCT_COMNGS comngs; comngs.set_bool ("is_new",is_new); comngs.set_str ("domain","/"); comngs.set_str ("name",getname()); // This triggers the REGISTER_USERACCT_COMNG objets comngs.getall ("group"); DIALOG dia; dia.newf_title (MSG_R(T_BASE),1,"",MSG_R(T_BASE)); int field_name = dia.getnb(); dia.newf_str (MSG_U(F_GROUPNAME,"Group name"),name); if (is_new) gid = groups.getnew(); dia.newf_num (MSG_U(F_GROUPID,"Group ID"),gid); // We split the member into several lines so they are easily // readable. The edit buffer of the user interface limits // the lenght anyway. SSTRINGS linemems; { SSTRINGS sorted; sorted.append(tbmem); sorted.sort(); SSTRING *line = new SSTRING; linemems.add (line); int nbmem = tbmem.getnb(); for (int i=0; igetlen() > 40){ line = new SSTRING; linemems.add (line); } if (!line->is_empty()) line->append (" "); line->append (sorted.getitem(i)->get()); } } int field_altmem = dia.getnb(); for (int i=0; icmp(user)==0){ tbmem.remove_del (i); ret = 1; break; } } return ret; } /* Add one user as a member of a group */ PUBLIC void GROUP::addmember(const char *user) { tbmem.add (new SSTRING(user)); } /* Return true is a user is a member of this group (alternate group) */ PUBLIC bool GROUP::is_member(const char *user) { bool ret = false; int n = tbmem.getnb(); for (int i=0; icmp(user)==0){ ret = true; break; } } return ret; } static void group_locate (const char *gname, bool ) { GROUPS grs; GROUP *g = grs.getitem (gname); if (g != NULL){ USERS users; g->edit(users,grs); } } static void group_list (SSTRINGS &tb) { GROUPS grs; for (int i=0; igetname())); } } #include static PUBLISH_VARIABLES_MSG group_var_list[]={ {"createhome",P_MSG_R(F_DIFFDIR)}, {"homebase",P_MSG_R(F_HOMEBASE)}, {"home-permission",P_MSG_R(F_CREATEPERM)}, { NULL, NULL } }; static REGISTER_VARIABLES group_registry1("group","groups",group_var_list ,NULL,group_locate,group_list);