/* * grpconv - create or update /etc/gshadow with information from * /etc/group. * * Copyright (C) 1996, Marek Michalkiewicz * * This program may be freely used and distributed. If you improve * it, please send me your changes. Thanks! */ #include #include #include #include #include #include #include #include #include #include "prototypes.h" #ifdef SHADOWGRP #include "groupio.h" #include "sgroupio.h" #include "rcsid.h" RCSID(PKG_VER "$Id: grpconv.c,v 1.11 2000/08/26 18:27:18 marekm Exp $") static int group_locked = 0; static int gshadow_locked = 0; /* local function prototypes */ static void fail_exit(int); static void fail_exit(int status) { if (group_locked) gr_unlock(); if (gshadow_locked) sgr_unlock(); exit(status); } int main(int argc, char **argv) { const struct group *gr; struct group grent; const struct sgrp *sg; struct sgrp sgent; char *Prog = argv[0]; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); if (!gr_lock()) { fprintf(stderr, _("%s: can't lock group file\n"), Prog); fail_exit(5); } group_locked++; if (!gr_open(O_RDWR)) { fprintf(stderr, _("%s: can't open group file\n"), Prog); fail_exit(1); } if (!sgr_lock()) { fprintf(stderr, _("%s: can't lock shadow group file\n"), Prog); fail_exit(5); } gshadow_locked++; if (!sgr_open(O_CREAT | O_RDWR)) { fprintf(stderr, _("%s: can't open shadow group file\n"), Prog); fail_exit(1); } /* * Remove /etc/gshadow entries for groups not in /etc/group. */ sgr_rewind(); while ((sg = sgr_next())) { if (gr_locate(sg->sg_name)) continue; if (!sgr_remove(sg->sg_name)) { /* * This shouldn't happen (the entry exists) but... */ fprintf(stderr, _("%s: can't remove shadow group %s\n"), Prog, sg->sg_name); fail_exit(3); } } /* * Update shadow group passwords if non-shadow password is not "x". * Add any missing shadow group entries. */ gr_rewind(); while ((gr = gr_next())) { sg = sgr_locate(gr->gr_name); if (sg) { #if 0 /* because of sg_mem, but see below */ if (strcmp(gr->gr_passwd, SHADOW_PASSWD_STRING) == 0) continue; #endif /* update existing shadow group entry */ sgent = *sg; if (strcmp(gr->gr_passwd, SHADOW_PASSWD_STRING) != 0) sgent.sg_passwd = gr->gr_passwd; } else { static char *empty = 0; /* add new shadow group entry */ memset(&sgent, 0, sizeof sgent); sgent.sg_name = gr->gr_name; sgent.sg_passwd = gr->gr_passwd; sgent.sg_adm = ∅ } /* * XXX - sg_mem is redundant, it is currently always a copy * of gr_mem. Very few programs actually use sg_mem, and * all of them are in the shadow suite... Maybe this field * could be used for something else? Any suggestions? */ sgent.sg_mem = gr->gr_mem; if (!sgr_update(&sgent)) { fprintf(stderr, _("%s: can't update shadow entry for %s\n"), Prog, sgent.sg_name); fail_exit(3); } /* remove password from /etc/group */ grent = *gr; grent.gr_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */ if (!gr_update(&grent)) { fprintf(stderr, _("%s: can't update entry for group %s\n"), Prog, grent.gr_name); fail_exit(3); } } if (!sgr_close()) { fprintf(stderr, _("%s: can't update shadow group file\n"), Prog); fail_exit(3); } if (!gr_close()) { fprintf(stderr, _("%s: can't update group file\n"), Prog); fail_exit(3); } sgr_unlock(); gr_unlock(); return 0; } #else /* !SHADOWGRP */ int main(int argc, char **argv) { setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); fprintf(stderr, _("%s: not configured for shadow group support.\n"), argv[0]); exit(1); } #endif /* !SHADOWGRP */