Call ceod in addmember and addclub
[public/pyceo-broken.git] / src / addmember.c
1 #include <unistd.h>
2 #include <sys/types.h>
3 #include <sys/wait.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <getopt.h>
7 #include <ctype.h>
8 #include <pwd.h>
9 #include <grp.h>
10 #include <errno.h>
11 #include <libgen.h>
12 #include <syslog.h>
13
14 #include "util.h"
15 #include "common.h"
16 #include "config.h"
17 #include "ldap.h"
18 #include "krb5.h"
19 #include "kadm.h"
20 #include "addhomedir.h"
21 #include "ceo.pb-c.h"
22
23 char *prog = NULL;
24
25 static int use_stdin = 0;
26
27 static char *name = NULL;
28 static char *userid = NULL;
29 static char *program = NULL;
30 static char password[1024];
31
32 static struct option opts[] = {
33     { "stdin", 0, NULL, 's' },
34     { NULL, 0, NULL, '\0' },
35 };
36
37 const char *default_lib_dir = "/usr/lib/ceod";
38 const char *lib_dir;
39
40 static void usage() {
41     fprintf(stderr, "Usage: %s userid realname [program]\n", prog);
42     exit(2);
43 }
44
45 int addmember(void) {
46     struct strbuf preq = STRBUF_INIT;
47     struct strbuf pret = STRBUF_INIT;
48     char cpath[1024];
49     char *cargv[] = { "ceoc", "adduser", NULL };
50
51     if (snprintf(cpath, sizeof(cpath), "%s/ceoc", lib_dir) >= sizeof(cpath))
52         fatal("path too long");
53
54     if (ceo_read_password(password, sizeof(password), use_stdin))
55         return 1;
56
57     Ceo__AddUser req;
58     ceo__add_user__init(&req);
59
60     req.username = userid;
61     req.password = password;
62     req.program  = program;
63     req.realname = name;
64     req.type = CEO__ADD_USER__TYPE__MEMBER;
65
66     strbuf_grow(&preq, ceo__add_user__get_packed_size(&req));
67     strbuf_setlen(&preq, ceo__add_user__pack(&req, (uint8_t *)preq.buf));
68
69     if (spawnvem(cpath, cargv, environ, &preq, &pret, 0))
70         return 1;
71
72     Ceo__AddUserResponse *ret = ceo__add_user_response__unpack(&protobuf_c_default_allocator,
73                                                                pret.len, (uint8_t *)pret.buf);
74     if (!ret)
75         fatal("failed to unpack response");
76
77     for (int i = 0; i < ret->n_messages; i++) {
78         if (ret->messages[i]->status)
79             error("%s", ret->messages[i]->message);
80         else
81             notice("%s", ret->messages[i]->message);
82     }
83
84     return 0;
85 }
86
87 int main(int argc, char *argv[]) {
88     int opt;
89
90     prog = basename(argv[0]);
91     init_log(prog, 0, LOG_AUTHPRIV);
92
93     configure();
94
95     while ((opt = getopt_long(argc, argv, "", opts, NULL)) != -1) {
96         switch (opt) {
97             case 's':
98                 use_stdin = 1;
99                 break;
100             case '?':
101                 usage();
102                 break;
103             default:
104                 fatal("error parsing arguments");
105         }
106     }
107
108     if (argc - optind != 2 && argc - optind != 3)
109         usage();
110
111     userid = argv[optind++];
112     name = argv[optind++];
113
114     if (argc - optind)
115         program = argv[optind++];
116
117     lib_dir = getenv("CEO_LIB_DIR") ?: default_lib_dir;
118
119     return addmember();
120 }