1 | /*
|
---|
2 | * Unix SMB/CIFS implementation.
|
---|
3 | * Local SAM access routines
|
---|
4 | * Copyright (C) Volker Lendecke 2006
|
---|
5 | *
|
---|
6 | * This program is free software; you can redistribute it and/or modify
|
---|
7 | * it under the terms of the GNU General Public License as published by
|
---|
8 | * the Free Software Foundation; either version 3 of the License, or
|
---|
9 | * (at your option) any later version.
|
---|
10 | *
|
---|
11 | * This program is distributed in the hope that it will be useful,
|
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | * GNU General Public License for more details.
|
---|
15 | *
|
---|
16 | * You should have received a copy of the GNU General Public License
|
---|
17 | * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
---|
18 | */
|
---|
19 |
|
---|
20 |
|
---|
21 | #include "includes.h"
|
---|
22 | #include "utils/net.h"
|
---|
23 |
|
---|
24 | /*
|
---|
25 | * Set a user's data
|
---|
26 | */
|
---|
27 |
|
---|
28 | static int net_sam_userset(struct net_context *c, int argc, const char **argv,
|
---|
29 | const char *field,
|
---|
30 | bool (*fn)(struct samu *, const char *,
|
---|
31 | enum pdb_value_state))
|
---|
32 | {
|
---|
33 | struct samu *sam_acct = NULL;
|
---|
34 | DOM_SID sid;
|
---|
35 | enum lsa_SidType type;
|
---|
36 | const char *dom, *name;
|
---|
37 | NTSTATUS status;
|
---|
38 |
|
---|
39 | if (argc != 2 || c->display_usage) {
|
---|
40 | d_fprintf(stderr, "usage: net sam set %s <user> <value>\n",
|
---|
41 | field);
|
---|
42 | return -1;
|
---|
43 | }
|
---|
44 |
|
---|
45 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
46 | &dom, &name, &sid, &type)) {
|
---|
47 | d_fprintf(stderr, "Could not find name %s\n", argv[0]);
|
---|
48 | return -1;
|
---|
49 | }
|
---|
50 |
|
---|
51 | if (type != SID_NAME_USER) {
|
---|
52 | d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
|
---|
53 | sid_type_lookup(type));
|
---|
54 | return -1;
|
---|
55 | }
|
---|
56 |
|
---|
57 | if ( !(sam_acct = samu_new( NULL )) ) {
|
---|
58 | d_fprintf(stderr, "Internal error\n");
|
---|
59 | return -1;
|
---|
60 | }
|
---|
61 |
|
---|
62 | if (!pdb_getsampwsid(sam_acct, &sid)) {
|
---|
63 | d_fprintf(stderr, "Loading user %s failed\n", argv[0]);
|
---|
64 | return -1;
|
---|
65 | }
|
---|
66 |
|
---|
67 | if (!fn(sam_acct, argv[1], PDB_CHANGED)) {
|
---|
68 | d_fprintf(stderr, "Internal error\n");
|
---|
69 | return -1;
|
---|
70 | }
|
---|
71 |
|
---|
72 | status = pdb_update_sam_account(sam_acct);
|
---|
73 | if (!NT_STATUS_IS_OK(status)) {
|
---|
74 | d_fprintf(stderr, "Updating sam account %s failed with %s\n",
|
---|
75 | argv[0], nt_errstr(status));
|
---|
76 | return -1;
|
---|
77 | }
|
---|
78 |
|
---|
79 | TALLOC_FREE(sam_acct);
|
---|
80 |
|
---|
81 | d_printf("Updated %s for %s\\%s to %s\n", field, dom, name, argv[1]);
|
---|
82 | return 0;
|
---|
83 | }
|
---|
84 |
|
---|
85 | static int net_sam_set_fullname(struct net_context *c, int argc,
|
---|
86 | const char **argv)
|
---|
87 | {
|
---|
88 | return net_sam_userset(c, argc, argv, "fullname",
|
---|
89 | pdb_set_fullname);
|
---|
90 | }
|
---|
91 |
|
---|
92 | static int net_sam_set_logonscript(struct net_context *c, int argc,
|
---|
93 | const char **argv)
|
---|
94 | {
|
---|
95 | return net_sam_userset(c, argc, argv, "logonscript",
|
---|
96 | pdb_set_logon_script);
|
---|
97 | }
|
---|
98 |
|
---|
99 | static int net_sam_set_profilepath(struct net_context *c, int argc,
|
---|
100 | const char **argv)
|
---|
101 | {
|
---|
102 | return net_sam_userset(c, argc, argv, "profilepath",
|
---|
103 | pdb_set_profile_path);
|
---|
104 | }
|
---|
105 |
|
---|
106 | static int net_sam_set_homedrive(struct net_context *c, int argc,
|
---|
107 | const char **argv)
|
---|
108 | {
|
---|
109 | return net_sam_userset(c, argc, argv, "homedrive",
|
---|
110 | pdb_set_dir_drive);
|
---|
111 | }
|
---|
112 |
|
---|
113 | static int net_sam_set_homedir(struct net_context *c, int argc,
|
---|
114 | const char **argv)
|
---|
115 | {
|
---|
116 | return net_sam_userset(c, argc, argv, "homedir",
|
---|
117 | pdb_set_homedir);
|
---|
118 | }
|
---|
119 |
|
---|
120 | static int net_sam_set_workstations(struct net_context *c, int argc,
|
---|
121 | const char **argv)
|
---|
122 | {
|
---|
123 | return net_sam_userset(c, argc, argv, "workstations",
|
---|
124 | pdb_set_workstations);
|
---|
125 | }
|
---|
126 |
|
---|
127 | /*
|
---|
128 | * Set account flags
|
---|
129 | */
|
---|
130 |
|
---|
131 | static int net_sam_set_userflag(struct net_context *c, int argc,
|
---|
132 | const char **argv, const char *field,
|
---|
133 | uint16 flag)
|
---|
134 | {
|
---|
135 | struct samu *sam_acct = NULL;
|
---|
136 | DOM_SID sid;
|
---|
137 | enum lsa_SidType type;
|
---|
138 | const char *dom, *name;
|
---|
139 | NTSTATUS status;
|
---|
140 | uint16 acct_flags;
|
---|
141 |
|
---|
142 | if ((argc != 2) || c->display_usage ||
|
---|
143 | (!strequal(argv[1], "yes") &&
|
---|
144 | !strequal(argv[1], "no"))) {
|
---|
145 | d_fprintf(stderr, "usage: net sam set %s <user> [yes|no]\n",
|
---|
146 | field);
|
---|
147 | return -1;
|
---|
148 | }
|
---|
149 |
|
---|
150 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
151 | &dom, &name, &sid, &type)) {
|
---|
152 | d_fprintf(stderr, "Could not find name %s\n", argv[0]);
|
---|
153 | return -1;
|
---|
154 | }
|
---|
155 |
|
---|
156 | if (type != SID_NAME_USER) {
|
---|
157 | d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
|
---|
158 | sid_type_lookup(type));
|
---|
159 | return -1;
|
---|
160 | }
|
---|
161 |
|
---|
162 | if ( !(sam_acct = samu_new( NULL )) ) {
|
---|
163 | d_fprintf(stderr, "Internal error\n");
|
---|
164 | return -1;
|
---|
165 | }
|
---|
166 |
|
---|
167 | if (!pdb_getsampwsid(sam_acct, &sid)) {
|
---|
168 | d_fprintf(stderr, "Loading user %s failed\n", argv[0]);
|
---|
169 | return -1;
|
---|
170 | }
|
---|
171 |
|
---|
172 | acct_flags = pdb_get_acct_ctrl(sam_acct);
|
---|
173 |
|
---|
174 | if (strequal(argv[1], "yes")) {
|
---|
175 | acct_flags |= flag;
|
---|
176 | } else {
|
---|
177 | acct_flags &= ~flag;
|
---|
178 | }
|
---|
179 |
|
---|
180 | pdb_set_acct_ctrl(sam_acct, acct_flags, PDB_CHANGED);
|
---|
181 |
|
---|
182 | status = pdb_update_sam_account(sam_acct);
|
---|
183 | if (!NT_STATUS_IS_OK(status)) {
|
---|
184 | d_fprintf(stderr, "Updating sam account %s failed with %s\n",
|
---|
185 | argv[0], nt_errstr(status));
|
---|
186 | return -1;
|
---|
187 | }
|
---|
188 |
|
---|
189 | TALLOC_FREE(sam_acct);
|
---|
190 |
|
---|
191 | d_fprintf(stderr, "Updated flag %s for %s\\%s to %s\n", field, dom,
|
---|
192 | name, argv[1]);
|
---|
193 | return 0;
|
---|
194 | }
|
---|
195 |
|
---|
196 | static int net_sam_set_disabled(struct net_context *c, int argc,
|
---|
197 | const char **argv)
|
---|
198 | {
|
---|
199 | return net_sam_set_userflag(c, argc, argv, "disabled", ACB_DISABLED);
|
---|
200 | }
|
---|
201 |
|
---|
202 | static int net_sam_set_pwnotreq(struct net_context *c, int argc,
|
---|
203 | const char **argv)
|
---|
204 | {
|
---|
205 | return net_sam_set_userflag(c, argc, argv, "pwnotreq", ACB_PWNOTREQ);
|
---|
206 | }
|
---|
207 |
|
---|
208 | static int net_sam_set_autolock(struct net_context *c, int argc,
|
---|
209 | const char **argv)
|
---|
210 | {
|
---|
211 | return net_sam_set_userflag(c, argc, argv, "autolock", ACB_AUTOLOCK);
|
---|
212 | }
|
---|
213 |
|
---|
214 | static int net_sam_set_pwnoexp(struct net_context *c, int argc,
|
---|
215 | const char **argv)
|
---|
216 | {
|
---|
217 | return net_sam_set_userflag(c, argc, argv, "pwnoexp", ACB_PWNOEXP);
|
---|
218 | }
|
---|
219 |
|
---|
220 | /*
|
---|
221 | * Set pass last change time, based on force pass change now
|
---|
222 | */
|
---|
223 |
|
---|
224 | static int net_sam_set_pwdmustchangenow(struct net_context *c, int argc,
|
---|
225 | const char **argv)
|
---|
226 | {
|
---|
227 | struct samu *sam_acct = NULL;
|
---|
228 | DOM_SID sid;
|
---|
229 | enum lsa_SidType type;
|
---|
230 | const char *dom, *name;
|
---|
231 | NTSTATUS status;
|
---|
232 |
|
---|
233 | if ((argc != 2) || c->display_usage ||
|
---|
234 | (!strequal(argv[1], "yes") &&
|
---|
235 | !strequal(argv[1], "no"))) {
|
---|
236 | d_fprintf(stderr, "usage: net sam set pwdmustchangenow <user> [yes|no]\n");
|
---|
237 | return -1;
|
---|
238 | }
|
---|
239 |
|
---|
240 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
241 | &dom, &name, &sid, &type)) {
|
---|
242 | d_fprintf(stderr, "Could not find name %s\n", argv[0]);
|
---|
243 | return -1;
|
---|
244 | }
|
---|
245 |
|
---|
246 | if (type != SID_NAME_USER) {
|
---|
247 | d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
|
---|
248 | sid_type_lookup(type));
|
---|
249 | return -1;
|
---|
250 | }
|
---|
251 |
|
---|
252 | if ( !(sam_acct = samu_new( NULL )) ) {
|
---|
253 | d_fprintf(stderr, "Internal error\n");
|
---|
254 | return -1;
|
---|
255 | }
|
---|
256 |
|
---|
257 | if (!pdb_getsampwsid(sam_acct, &sid)) {
|
---|
258 | d_fprintf(stderr, "Loading user %s failed\n", argv[0]);
|
---|
259 | return -1;
|
---|
260 | }
|
---|
261 |
|
---|
262 | if (strequal(argv[1], "yes")) {
|
---|
263 | pdb_set_pass_last_set_time(sam_acct, 0, PDB_CHANGED);
|
---|
264 | } else {
|
---|
265 | pdb_set_pass_last_set_time(sam_acct, time(NULL), PDB_CHANGED);
|
---|
266 | }
|
---|
267 |
|
---|
268 | status = pdb_update_sam_account(sam_acct);
|
---|
269 | if (!NT_STATUS_IS_OK(status)) {
|
---|
270 | d_fprintf(stderr, "Updating sam account %s failed with %s\n",
|
---|
271 | argv[0], nt_errstr(status));
|
---|
272 | return -1;
|
---|
273 | }
|
---|
274 |
|
---|
275 | TALLOC_FREE(sam_acct);
|
---|
276 |
|
---|
277 | d_fprintf(stderr, "Updated 'user must change password at next logon' for %s\\%s to %s\n", dom,
|
---|
278 | name, argv[1]);
|
---|
279 | return 0;
|
---|
280 | }
|
---|
281 |
|
---|
282 |
|
---|
283 | /*
|
---|
284 | * Set a user's or a group's comment
|
---|
285 | */
|
---|
286 |
|
---|
287 | static int net_sam_set_comment(struct net_context *c, int argc,
|
---|
288 | const char **argv)
|
---|
289 | {
|
---|
290 | GROUP_MAP map;
|
---|
291 | DOM_SID sid;
|
---|
292 | enum lsa_SidType type;
|
---|
293 | const char *dom, *name;
|
---|
294 | NTSTATUS status;
|
---|
295 |
|
---|
296 | if (argc != 2 || c->display_usage) {
|
---|
297 | d_fprintf(stderr, "usage: net sam set comment <name> "
|
---|
298 | "<comment>\n");
|
---|
299 | return -1;
|
---|
300 | }
|
---|
301 |
|
---|
302 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
303 | &dom, &name, &sid, &type)) {
|
---|
304 | d_fprintf(stderr, "Could not find name %s\n", argv[0]);
|
---|
305 | return -1;
|
---|
306 | }
|
---|
307 |
|
---|
308 | if (type == SID_NAME_USER) {
|
---|
309 | return net_sam_userset(c, argc, argv, "comment",
|
---|
310 | pdb_set_acct_desc);
|
---|
311 | }
|
---|
312 |
|
---|
313 | if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
|
---|
314 | (type != SID_NAME_WKN_GRP)) {
|
---|
315 | d_fprintf(stderr, "%s is a %s, not a group\n", argv[0],
|
---|
316 | sid_type_lookup(type));
|
---|
317 | return -1;
|
---|
318 | }
|
---|
319 |
|
---|
320 | if (!pdb_getgrsid(&map, sid)) {
|
---|
321 | d_fprintf(stderr, "Could not load group %s\n", argv[0]);
|
---|
322 | return -1;
|
---|
323 | }
|
---|
324 |
|
---|
325 | fstrcpy(map.comment, argv[1]);
|
---|
326 |
|
---|
327 | status = pdb_update_group_mapping_entry(&map);
|
---|
328 |
|
---|
329 | if (!NT_STATUS_IS_OK(status)) {
|
---|
330 | d_fprintf(stderr, "Updating group mapping entry failed with "
|
---|
331 | "%s\n", nt_errstr(status));
|
---|
332 | return -1;
|
---|
333 | }
|
---|
334 |
|
---|
335 | d_printf("Updated comment of group %s\\%s to %s\n", dom, name,
|
---|
336 | argv[1]);
|
---|
337 |
|
---|
338 | return 0;
|
---|
339 | }
|
---|
340 |
|
---|
341 | static int net_sam_set(struct net_context *c, int argc, const char **argv)
|
---|
342 | {
|
---|
343 | struct functable func[] = {
|
---|
344 | {
|
---|
345 | "homedir",
|
---|
346 | net_sam_set_homedir,
|
---|
347 | NET_TRANSPORT_LOCAL,
|
---|
348 | "Change a user's home directory",
|
---|
349 | "net sam set homedir\n"
|
---|
350 | " Change a user's home directory"
|
---|
351 | },
|
---|
352 | {
|
---|
353 | "profilepath",
|
---|
354 | net_sam_set_profilepath,
|
---|
355 | NET_TRANSPORT_LOCAL,
|
---|
356 | "Change a user's profile path",
|
---|
357 | "net sam set profilepath\n"
|
---|
358 | " Change a user's profile path"
|
---|
359 | },
|
---|
360 | {
|
---|
361 | "comment",
|
---|
362 | net_sam_set_comment,
|
---|
363 | NET_TRANSPORT_LOCAL,
|
---|
364 | "Change a users or groups description",
|
---|
365 | "net sam set comment\n"
|
---|
366 | " Change a users or groups description"
|
---|
367 | },
|
---|
368 | {
|
---|
369 | "fullname",
|
---|
370 | net_sam_set_fullname,
|
---|
371 | NET_TRANSPORT_LOCAL,
|
---|
372 | "Change a user's full name",
|
---|
373 | "net sam set fullname\n"
|
---|
374 | " Change a user's full name"
|
---|
375 | },
|
---|
376 | {
|
---|
377 | "logonscript",
|
---|
378 | net_sam_set_logonscript,
|
---|
379 | NET_TRANSPORT_LOCAL,
|
---|
380 | "Change a user's logon script",
|
---|
381 | "net sam set logonscript\n"
|
---|
382 | " Change a user's logon script"
|
---|
383 | },
|
---|
384 | {
|
---|
385 | "homedrive",
|
---|
386 | net_sam_set_homedrive,
|
---|
387 | NET_TRANSPORT_LOCAL,
|
---|
388 | "Change a user's home drive",
|
---|
389 | "net sam set homedrive\n"
|
---|
390 | " Change a user's home drive"
|
---|
391 | },
|
---|
392 | {
|
---|
393 | "workstations",
|
---|
394 | net_sam_set_workstations,
|
---|
395 | NET_TRANSPORT_LOCAL,
|
---|
396 | "Change a user's allowed workstations",
|
---|
397 | "net sam set workstations\n"
|
---|
398 | " Change a user's allowed workstations"
|
---|
399 | },
|
---|
400 | {
|
---|
401 | "disabled",
|
---|
402 | net_sam_set_disabled,
|
---|
403 | NET_TRANSPORT_LOCAL,
|
---|
404 | "Disable/Enable a user",
|
---|
405 | "net sam set disable\n"
|
---|
406 | " Disable/Enable a user"
|
---|
407 | },
|
---|
408 | {
|
---|
409 | "pwnotreq",
|
---|
410 | net_sam_set_pwnotreq,
|
---|
411 | NET_TRANSPORT_LOCAL,
|
---|
412 | "Disable/Enable the password not required flag",
|
---|
413 | "net sam set pwnotreq\n"
|
---|
414 | " Disable/Enable the password not required flag"
|
---|
415 | },
|
---|
416 | {
|
---|
417 | "autolock",
|
---|
418 | net_sam_set_autolock,
|
---|
419 | NET_TRANSPORT_LOCAL,
|
---|
420 | "Disable/Enable a user's lockout flag",
|
---|
421 | "net sam set autolock\n"
|
---|
422 | " Disable/Enable a user's lockout flag"
|
---|
423 | },
|
---|
424 | {
|
---|
425 | "pwnoexp",
|
---|
426 | net_sam_set_pwnoexp,
|
---|
427 | NET_TRANSPORT_LOCAL,
|
---|
428 | "Disable/Enable whether a user's pw does not expire",
|
---|
429 | "net sam set pwnoexp\n"
|
---|
430 | " Disable/Enable whether a user's pw does not expire"
|
---|
431 | },
|
---|
432 | {
|
---|
433 | "pwdmustchangenow",
|
---|
434 | net_sam_set_pwdmustchangenow,
|
---|
435 | NET_TRANSPORT_LOCAL,
|
---|
436 | "Force users password must change at next logon",
|
---|
437 | "net sam set pwdmustchangenow\n"
|
---|
438 | " Force users password must change at next logon"
|
---|
439 | },
|
---|
440 | {NULL, NULL, 0, NULL, NULL}
|
---|
441 | };
|
---|
442 |
|
---|
443 | return net_run_function(c, argc, argv, "net sam set", func);
|
---|
444 | }
|
---|
445 |
|
---|
446 | /*
|
---|
447 | * Manage account policies
|
---|
448 | */
|
---|
449 |
|
---|
450 | static int net_sam_policy_set(struct net_context *c, int argc, const char **argv)
|
---|
451 | {
|
---|
452 | const char *account_policy = NULL;
|
---|
453 | uint32 value = 0;
|
---|
454 | uint32 old_value = 0;
|
---|
455 | int field;
|
---|
456 | char *endptr;
|
---|
457 |
|
---|
458 | if (argc != 2 || c->display_usage) {
|
---|
459 | d_fprintf(stderr, "usage: net sam policy set "
|
---|
460 | "\"<account policy>\" <value> \n");
|
---|
461 | return -1;
|
---|
462 | }
|
---|
463 |
|
---|
464 | account_policy = argv[0];
|
---|
465 | field = account_policy_name_to_fieldnum(account_policy);
|
---|
466 |
|
---|
467 | if (strequal(argv[1], "forever") || strequal(argv[1], "never")
|
---|
468 | || strequal(argv[1], "off")) {
|
---|
469 | value = -1;
|
---|
470 | }
|
---|
471 | else {
|
---|
472 | value = strtoul(argv[1], &endptr, 10);
|
---|
473 |
|
---|
474 | if ((endptr == argv[1]) || (endptr[0] != '\0')) {
|
---|
475 | d_printf("Unable to set policy \"%s\"! Invalid value "
|
---|
476 | "\"%s\".\n",
|
---|
477 | account_policy, argv[1]);
|
---|
478 | return -1;
|
---|
479 | }
|
---|
480 | }
|
---|
481 |
|
---|
482 | if (field == 0) {
|
---|
483 | const char **names;
|
---|
484 | int i, count;
|
---|
485 |
|
---|
486 | account_policy_names_list(&names, &count);
|
---|
487 | d_fprintf(stderr, "No account policy \"%s\"!\n\n", argv[0]);
|
---|
488 | d_fprintf(stderr, "Valid account policies are:\n");
|
---|
489 |
|
---|
490 | for (i=0; i<count; i++) {
|
---|
491 | d_fprintf(stderr, "%s\n", names[i]);
|
---|
492 | }
|
---|
493 |
|
---|
494 | SAFE_FREE(names);
|
---|
495 | return -1;
|
---|
496 | }
|
---|
497 |
|
---|
498 | if (!pdb_get_account_policy(field, &old_value)) {
|
---|
499 | d_fprintf(stderr, "Valid account policy, but unable to fetch "
|
---|
500 | "value!\n");
|
---|
501 | } else {
|
---|
502 | d_printf("Account policy \"%s\" value was: %d\n", account_policy,
|
---|
503 | old_value);
|
---|
504 | }
|
---|
505 |
|
---|
506 | if (!pdb_set_account_policy(field, value)) {
|
---|
507 | d_fprintf(stderr, "Valid account policy, but unable to "
|
---|
508 | "set value!\n");
|
---|
509 | return -1;
|
---|
510 | } else {
|
---|
511 | d_printf("Account policy \"%s\" value is now: %d\n", account_policy,
|
---|
512 | value);
|
---|
513 | }
|
---|
514 |
|
---|
515 | return 0;
|
---|
516 | }
|
---|
517 |
|
---|
518 | static int net_sam_policy_show(struct net_context *c, int argc, const char **argv)
|
---|
519 | {
|
---|
520 | const char *account_policy = NULL;
|
---|
521 | uint32 old_value;
|
---|
522 | int field;
|
---|
523 |
|
---|
524 | if (argc != 1 || c->display_usage) {
|
---|
525 | d_fprintf(stderr, "usage: net sam policy show"
|
---|
526 | " \"<account policy>\" \n");
|
---|
527 | return -1;
|
---|
528 | }
|
---|
529 |
|
---|
530 | account_policy = argv[0];
|
---|
531 | field = account_policy_name_to_fieldnum(account_policy);
|
---|
532 |
|
---|
533 | if (field == 0) {
|
---|
534 | const char **names;
|
---|
535 | int count;
|
---|
536 | int i;
|
---|
537 | account_policy_names_list(&names, &count);
|
---|
538 | d_fprintf(stderr, "No account policy by that name!\n");
|
---|
539 | if (count != 0) {
|
---|
540 | d_fprintf(stderr, "Valid account policies "
|
---|
541 | "are:\n");
|
---|
542 | for (i=0; i<count; i++) {
|
---|
543 | d_fprintf(stderr, "%s\n", names[i]);
|
---|
544 | }
|
---|
545 | }
|
---|
546 | SAFE_FREE(names);
|
---|
547 | return -1;
|
---|
548 | }
|
---|
549 |
|
---|
550 | if (!pdb_get_account_policy(field, &old_value)) {
|
---|
551 | fprintf(stderr, "Valid account policy, but unable to "
|
---|
552 | "fetch value!\n");
|
---|
553 | return -1;
|
---|
554 | }
|
---|
555 |
|
---|
556 | printf("Account policy \"%s\" description: %s\n",
|
---|
557 | account_policy, account_policy_get_desc(field));
|
---|
558 | printf("Account policy \"%s\" value is: %d\n", account_policy,
|
---|
559 | old_value);
|
---|
560 | return 0;
|
---|
561 | }
|
---|
562 |
|
---|
563 | static int net_sam_policy_list(struct net_context *c, int argc, const char **argv)
|
---|
564 | {
|
---|
565 | const char **names;
|
---|
566 | int count;
|
---|
567 | int i;
|
---|
568 |
|
---|
569 | if (c->display_usage) {
|
---|
570 | d_printf("Usage:\n"
|
---|
571 | "net sam policy list\n"
|
---|
572 | " List account policies\n");
|
---|
573 | return 0;
|
---|
574 | }
|
---|
575 |
|
---|
576 | account_policy_names_list(&names, &count);
|
---|
577 | if (count != 0) {
|
---|
578 | d_fprintf(stderr, "Valid account policies "
|
---|
579 | "are:\n");
|
---|
580 | for (i = 0; i < count ; i++) {
|
---|
581 | d_fprintf(stderr, "%s\n", names[i]);
|
---|
582 | }
|
---|
583 | }
|
---|
584 | SAFE_FREE(names);
|
---|
585 | return -1;
|
---|
586 | }
|
---|
587 |
|
---|
588 | static int net_sam_policy(struct net_context *c, int argc, const char **argv)
|
---|
589 | {
|
---|
590 | struct functable func[] = {
|
---|
591 | {
|
---|
592 | "list",
|
---|
593 | net_sam_policy_list,
|
---|
594 | NET_TRANSPORT_LOCAL,
|
---|
595 | "List account policies",
|
---|
596 | "net sam policy list\n"
|
---|
597 | " List account policies"
|
---|
598 | },
|
---|
599 | {
|
---|
600 | "show",
|
---|
601 | net_sam_policy_show,
|
---|
602 | NET_TRANSPORT_LOCAL,
|
---|
603 | "Show account policies",
|
---|
604 | "net sam policy show\n"
|
---|
605 | " Show account policies"
|
---|
606 | },
|
---|
607 | {
|
---|
608 | "set",
|
---|
609 | net_sam_policy_set,
|
---|
610 | NET_TRANSPORT_LOCAL,
|
---|
611 | "Change account policies",
|
---|
612 | "net sam policy set\n"
|
---|
613 | " Change account policies"
|
---|
614 | },
|
---|
615 | {NULL, NULL, 0, NULL, NULL}
|
---|
616 | };
|
---|
617 |
|
---|
618 | return net_run_function(c, argc, argv, "net sam policy", func);
|
---|
619 | }
|
---|
620 |
|
---|
621 | extern PRIVS privs[];
|
---|
622 |
|
---|
623 | static int net_sam_rights_list(struct net_context *c, int argc,
|
---|
624 | const char **argv)
|
---|
625 | {
|
---|
626 | SE_PRIV mask;
|
---|
627 |
|
---|
628 | if (argc > 1 || c->display_usage) {
|
---|
629 | d_fprintf(stderr, "usage: net sam rights list [privilege name]\n");
|
---|
630 | return -1;
|
---|
631 | }
|
---|
632 |
|
---|
633 | if (argc == 0) {
|
---|
634 | int i;
|
---|
635 | int num = count_all_privileges();
|
---|
636 |
|
---|
637 | for (i=0; i<num; i++) {
|
---|
638 | d_printf("%s\n", privs[i].name);
|
---|
639 | }
|
---|
640 | return 0;
|
---|
641 | }
|
---|
642 |
|
---|
643 | if (se_priv_from_name(argv[0], &mask)) {
|
---|
644 | DOM_SID *sids;
|
---|
645 | int i, num_sids;
|
---|
646 | NTSTATUS status;
|
---|
647 |
|
---|
648 | status = privilege_enum_sids(&mask, talloc_tos(),
|
---|
649 | &sids, &num_sids);
|
---|
650 | if (!NT_STATUS_IS_OK(status)) {
|
---|
651 | d_fprintf(stderr, "Could not list rights: %s\n",
|
---|
652 | nt_errstr(status));
|
---|
653 | return -1;
|
---|
654 | }
|
---|
655 |
|
---|
656 | for (i=0; i<num_sids; i++) {
|
---|
657 | const char *dom, *name;
|
---|
658 | enum lsa_SidType type;
|
---|
659 |
|
---|
660 | if (lookup_sid(talloc_tos(), &sids[i], &dom, &name,
|
---|
661 | &type)) {
|
---|
662 | d_printf("%s\\%s\n", dom, name);
|
---|
663 | }
|
---|
664 | else {
|
---|
665 | d_printf("%s\n", sid_string_tos(&sids[i]));
|
---|
666 | }
|
---|
667 | }
|
---|
668 | return 0;
|
---|
669 | }
|
---|
670 |
|
---|
671 | return -1;
|
---|
672 | }
|
---|
673 |
|
---|
674 | static int net_sam_rights_grant(struct net_context *c, int argc,
|
---|
675 | const char **argv)
|
---|
676 | {
|
---|
677 | DOM_SID sid;
|
---|
678 | enum lsa_SidType type;
|
---|
679 | const char *dom, *name;
|
---|
680 | SE_PRIV mask;
|
---|
681 |
|
---|
682 | if (argc != 2 || c->display_usage) {
|
---|
683 | d_fprintf(stderr, "usage: net sam rights grant <name> "
|
---|
684 | "<right>\n");
|
---|
685 | return -1;
|
---|
686 | }
|
---|
687 |
|
---|
688 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
689 | &dom, &name, &sid, &type)) {
|
---|
690 | d_fprintf(stderr, "Could not find name %s\n", argv[0]);
|
---|
691 | return -1;
|
---|
692 | }
|
---|
693 |
|
---|
694 | if (!se_priv_from_name(argv[1], &mask)) {
|
---|
695 | d_fprintf(stderr, "%s unknown\n", argv[1]);
|
---|
696 | return -1;
|
---|
697 | }
|
---|
698 |
|
---|
699 | if (!grant_privilege(&sid, &mask)) {
|
---|
700 | d_fprintf(stderr, "Could not grant privilege\n");
|
---|
701 | return -1;
|
---|
702 | }
|
---|
703 |
|
---|
704 | d_printf("Granted %s to %s\\%s\n", argv[1], dom, name);
|
---|
705 | return 0;
|
---|
706 | }
|
---|
707 |
|
---|
708 | static int net_sam_rights_revoke(struct net_context *c, int argc, const char **argv)
|
---|
709 | {
|
---|
710 | DOM_SID sid;
|
---|
711 | enum lsa_SidType type;
|
---|
712 | const char *dom, *name;
|
---|
713 | SE_PRIV mask;
|
---|
714 |
|
---|
715 | if (argc != 2 || c->display_usage) {
|
---|
716 | d_fprintf(stderr, "usage: net sam rights revoke <name> "
|
---|
717 | "<right>\n");
|
---|
718 | return -1;
|
---|
719 | }
|
---|
720 |
|
---|
721 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
722 | &dom, &name, &sid, &type)) {
|
---|
723 | d_fprintf(stderr, "Could not find name %s\n", argv[0]);
|
---|
724 | return -1;
|
---|
725 | }
|
---|
726 |
|
---|
727 | if (!se_priv_from_name(argv[1], &mask)) {
|
---|
728 | d_fprintf(stderr, "%s unknown\n", argv[1]);
|
---|
729 | return -1;
|
---|
730 | }
|
---|
731 |
|
---|
732 | if (!revoke_privilege(&sid, &mask)) {
|
---|
733 | d_fprintf(stderr, "Could not revoke privilege\n");
|
---|
734 | return -1;
|
---|
735 | }
|
---|
736 |
|
---|
737 | d_printf("Revoked %s from %s\\%s\n", argv[1], dom, name);
|
---|
738 | return 0;
|
---|
739 | }
|
---|
740 |
|
---|
741 | static int net_sam_rights(struct net_context *c, int argc, const char **argv)
|
---|
742 | {
|
---|
743 | struct functable func[] = {
|
---|
744 | {
|
---|
745 | "list",
|
---|
746 | net_sam_rights_list,
|
---|
747 | NET_TRANSPORT_LOCAL,
|
---|
748 | "List possible user rights",
|
---|
749 | "net sam rights list\n"
|
---|
750 | " List possible user rights"
|
---|
751 | },
|
---|
752 | {
|
---|
753 | "grant",
|
---|
754 | net_sam_rights_grant,
|
---|
755 | NET_TRANSPORT_LOCAL,
|
---|
756 | "Grant a right",
|
---|
757 | "net sam rights grant\n"
|
---|
758 | " Grant a right"
|
---|
759 | },
|
---|
760 | {
|
---|
761 | "revoke",
|
---|
762 | net_sam_rights_revoke,
|
---|
763 | NET_TRANSPORT_LOCAL,
|
---|
764 | "Revoke a right",
|
---|
765 | "net sam rights revoke\n"
|
---|
766 | " Revoke a right"
|
---|
767 | },
|
---|
768 | {NULL, NULL, 0, NULL, NULL}
|
---|
769 | };
|
---|
770 | return net_run_function(c, argc, argv, "net sam rights", func);
|
---|
771 | }
|
---|
772 |
|
---|
773 | /*
|
---|
774 | * Map a unix group to a domain group
|
---|
775 | */
|
---|
776 |
|
---|
777 | static NTSTATUS map_unix_group(const struct group *grp, GROUP_MAP *pmap)
|
---|
778 | {
|
---|
779 | NTSTATUS status;
|
---|
780 | GROUP_MAP map;
|
---|
781 | const char *grpname, *dom, *name;
|
---|
782 | uint32 rid;
|
---|
783 |
|
---|
784 | if (pdb_getgrgid(&map, grp->gr_gid)) {
|
---|
785 | return NT_STATUS_GROUP_EXISTS;
|
---|
786 | }
|
---|
787 |
|
---|
788 | map.gid = grp->gr_gid;
|
---|
789 | grpname = grp->gr_name;
|
---|
790 |
|
---|
791 | if (lookup_name(talloc_tos(), grpname, LOOKUP_NAME_LOCAL,
|
---|
792 | &dom, &name, NULL, NULL)) {
|
---|
793 |
|
---|
794 | const char *tmp = talloc_asprintf(
|
---|
795 | talloc_tos(), "Unix Group %s", grp->gr_name);
|
---|
796 |
|
---|
797 | DEBUG(5, ("%s exists as %s\\%s, retrying as \"%s\"\n",
|
---|
798 | grpname, dom, name, tmp));
|
---|
799 | grpname = tmp;
|
---|
800 | }
|
---|
801 |
|
---|
802 | if (lookup_name(talloc_tos(), grpname, LOOKUP_NAME_LOCAL,
|
---|
803 | NULL, NULL, NULL, NULL)) {
|
---|
804 | DEBUG(3, ("\"%s\" exists, can't map it\n", grp->gr_name));
|
---|
805 | return NT_STATUS_GROUP_EXISTS;
|
---|
806 | }
|
---|
807 |
|
---|
808 | fstrcpy(map.nt_name, grpname);
|
---|
809 |
|
---|
810 | if (pdb_rid_algorithm()) {
|
---|
811 | rid = algorithmic_pdb_gid_to_group_rid( grp->gr_gid );
|
---|
812 | } else {
|
---|
813 | if (!pdb_new_rid(&rid)) {
|
---|
814 | DEBUG(3, ("Could not get a new RID for %s\n",
|
---|
815 | grp->gr_name));
|
---|
816 | return NT_STATUS_ACCESS_DENIED;
|
---|
817 | }
|
---|
818 | }
|
---|
819 |
|
---|
820 | sid_compose(&map.sid, get_global_sam_sid(), rid);
|
---|
821 | map.sid_name_use = SID_NAME_DOM_GRP;
|
---|
822 | fstrcpy(map.comment, talloc_asprintf(talloc_tos(), "Unix Group %s",
|
---|
823 | grp->gr_name));
|
---|
824 |
|
---|
825 | status = pdb_add_group_mapping_entry(&map);
|
---|
826 | if (NT_STATUS_IS_OK(status)) {
|
---|
827 | *pmap = map;
|
---|
828 | }
|
---|
829 | return status;
|
---|
830 | }
|
---|
831 |
|
---|
832 | static int net_sam_mapunixgroup(struct net_context *c, int argc, const char **argv)
|
---|
833 | {
|
---|
834 | NTSTATUS status;
|
---|
835 | GROUP_MAP map;
|
---|
836 | struct group *grp;
|
---|
837 |
|
---|
838 | if (argc != 1 || c->display_usage) {
|
---|
839 | d_fprintf(stderr, "usage: net sam mapunixgroup <name>\n");
|
---|
840 | return -1;
|
---|
841 | }
|
---|
842 |
|
---|
843 | grp = getgrnam(argv[0]);
|
---|
844 | if (grp == NULL) {
|
---|
845 | d_fprintf(stderr, "Could not find group %s\n", argv[0]);
|
---|
846 | return -1;
|
---|
847 | }
|
---|
848 |
|
---|
849 | status = map_unix_group(grp, &map);
|
---|
850 |
|
---|
851 | if (!NT_STATUS_IS_OK(status)) {
|
---|
852 | d_fprintf(stderr, "Mapping group %s failed with %s\n",
|
---|
853 | argv[0], nt_errstr(status));
|
---|
854 | return -1;
|
---|
855 | }
|
---|
856 |
|
---|
857 | d_printf("Mapped unix group %s to SID %s\n", argv[0],
|
---|
858 | sid_string_tos(&map.sid));
|
---|
859 |
|
---|
860 | return 0;
|
---|
861 | }
|
---|
862 |
|
---|
863 | /*
|
---|
864 | * Remove a group mapping
|
---|
865 | */
|
---|
866 |
|
---|
867 | static NTSTATUS unmap_unix_group(const struct group *grp, GROUP_MAP *pmap)
|
---|
868 | {
|
---|
869 | NTSTATUS status;
|
---|
870 | GROUP_MAP map;
|
---|
871 | const char *grpname;
|
---|
872 | DOM_SID dom_sid;
|
---|
873 |
|
---|
874 | map.gid = grp->gr_gid;
|
---|
875 | grpname = grp->gr_name;
|
---|
876 |
|
---|
877 | if (!lookup_name(talloc_tos(), grpname, LOOKUP_NAME_LOCAL,
|
---|
878 | NULL, NULL, NULL, NULL)) {
|
---|
879 | DEBUG(3, ("\"%s\" does not exist, can't unmap it\n", grp->gr_name));
|
---|
880 | return NT_STATUS_NO_SUCH_GROUP;
|
---|
881 | }
|
---|
882 |
|
---|
883 | fstrcpy(map.nt_name, grpname);
|
---|
884 |
|
---|
885 | if (!pdb_gid_to_sid(map.gid, &dom_sid)) {
|
---|
886 | return NT_STATUS_UNSUCCESSFUL;
|
---|
887 | }
|
---|
888 |
|
---|
889 | status = pdb_delete_group_mapping_entry(dom_sid);
|
---|
890 |
|
---|
891 | return status;
|
---|
892 | }
|
---|
893 |
|
---|
894 | static int net_sam_unmapunixgroup(struct net_context *c, int argc, const char **argv)
|
---|
895 | {
|
---|
896 | NTSTATUS status;
|
---|
897 | GROUP_MAP map;
|
---|
898 | struct group *grp;
|
---|
899 |
|
---|
900 | if (argc != 1 || c->display_usage) {
|
---|
901 | d_fprintf(stderr, "usage: net sam unmapunixgroup <name>\n");
|
---|
902 | return -1;
|
---|
903 | }
|
---|
904 |
|
---|
905 | grp = getgrnam(argv[0]);
|
---|
906 | if (grp == NULL) {
|
---|
907 | d_fprintf(stderr, "Could not find mapping for group %s.\n", argv[0]);
|
---|
908 | return -1;
|
---|
909 | }
|
---|
910 |
|
---|
911 | status = unmap_unix_group(grp, &map);
|
---|
912 |
|
---|
913 | if (!NT_STATUS_IS_OK(status)) {
|
---|
914 | d_fprintf(stderr, "Unmapping group %s failed with %s.\n",
|
---|
915 | argv[0], nt_errstr(status));
|
---|
916 | return -1;
|
---|
917 | }
|
---|
918 |
|
---|
919 | d_printf("Unmapped unix group %s.\n", argv[0]);
|
---|
920 |
|
---|
921 | return 0;
|
---|
922 | }
|
---|
923 |
|
---|
924 | /*
|
---|
925 | * Create a local group
|
---|
926 | */
|
---|
927 |
|
---|
928 | static int net_sam_createlocalgroup(struct net_context *c, int argc, const char **argv)
|
---|
929 | {
|
---|
930 | NTSTATUS status;
|
---|
931 | uint32 rid;
|
---|
932 |
|
---|
933 | if (argc != 1 || c->display_usage) {
|
---|
934 | d_fprintf(stderr, "usage: net sam createlocalgroup <name>\n");
|
---|
935 | return -1;
|
---|
936 | }
|
---|
937 |
|
---|
938 | if (!winbind_ping()) {
|
---|
939 | d_fprintf(stderr, "winbind seems not to run. createlocalgroup "
|
---|
940 | "only works when winbind runs.\n");
|
---|
941 | return -1;
|
---|
942 | }
|
---|
943 |
|
---|
944 | status = pdb_create_alias(argv[0], &rid);
|
---|
945 |
|
---|
946 | if (!NT_STATUS_IS_OK(status)) {
|
---|
947 | d_fprintf(stderr, "Creating %s failed with %s\n",
|
---|
948 | argv[0], nt_errstr(status));
|
---|
949 | return -1;
|
---|
950 | }
|
---|
951 |
|
---|
952 | d_printf("Created local group %s with RID %d\n", argv[0], rid);
|
---|
953 |
|
---|
954 | return 0;
|
---|
955 | }
|
---|
956 |
|
---|
957 | /*
|
---|
958 | * Delete a local group
|
---|
959 | */
|
---|
960 |
|
---|
961 | static int net_sam_deletelocalgroup(struct net_context *c, int argc, const char **argv)
|
---|
962 | {
|
---|
963 | DOM_SID sid;
|
---|
964 | enum lsa_SidType type;
|
---|
965 | const char *dom, *name;
|
---|
966 | NTSTATUS status;
|
---|
967 |
|
---|
968 | if (argc != 1 || c->display_usage) {
|
---|
969 | d_fprintf(stderr, "usage: net sam deletelocalgroup <name>\n");
|
---|
970 | return -1;
|
---|
971 | }
|
---|
972 |
|
---|
973 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
974 | &dom, &name, &sid, &type)) {
|
---|
975 | d_fprintf(stderr, "Could not find %s.\n", argv[0]);
|
---|
976 | return -1;
|
---|
977 | }
|
---|
978 |
|
---|
979 | if (type != SID_NAME_ALIAS) {
|
---|
980 | d_fprintf(stderr, "%s is a %s, not a local group.\n", argv[0],
|
---|
981 | sid_type_lookup(type));
|
---|
982 | return -1;
|
---|
983 | }
|
---|
984 |
|
---|
985 | status = pdb_delete_alias(&sid);
|
---|
986 |
|
---|
987 | if (!NT_STATUS_IS_OK(status)) {
|
---|
988 | d_fprintf(stderr, "Deleting local group %s failed with %s\n",
|
---|
989 | argv[0], nt_errstr(status));
|
---|
990 | return -1;
|
---|
991 | }
|
---|
992 |
|
---|
993 | d_printf("Deleted local group %s.\n", argv[0]);
|
---|
994 |
|
---|
995 | return 0;
|
---|
996 | }
|
---|
997 |
|
---|
998 | /*
|
---|
999 | * Create a builtin group
|
---|
1000 | */
|
---|
1001 |
|
---|
1002 | static int net_sam_createbuiltingroup(struct net_context *c, int argc, const char **argv)
|
---|
1003 | {
|
---|
1004 | NTSTATUS status;
|
---|
1005 | uint32 rid;
|
---|
1006 | enum lsa_SidType type;
|
---|
1007 | fstring groupname;
|
---|
1008 | DOM_SID sid;
|
---|
1009 |
|
---|
1010 | if (argc != 1 || c->display_usage) {
|
---|
1011 | d_fprintf(stderr, "usage: net sam createbuiltingroup <name>\n");
|
---|
1012 | return -1;
|
---|
1013 | }
|
---|
1014 |
|
---|
1015 | if (!winbind_ping()) {
|
---|
1016 | d_fprintf(stderr, "winbind seems not to run. createbuiltingroup "
|
---|
1017 | "only works when winbind runs.\n");
|
---|
1018 | return -1;
|
---|
1019 | }
|
---|
1020 |
|
---|
1021 | /* validate the name and get the group */
|
---|
1022 |
|
---|
1023 | fstrcpy( groupname, "BUILTIN\\" );
|
---|
1024 | fstrcat( groupname, argv[0] );
|
---|
1025 |
|
---|
1026 | if ( !lookup_name(talloc_tos(), groupname, LOOKUP_NAME_ALL, NULL,
|
---|
1027 | NULL, &sid, &type)) {
|
---|
1028 | d_fprintf(stderr, "%s is not a BUILTIN group\n", argv[0]);
|
---|
1029 | return -1;
|
---|
1030 | }
|
---|
1031 |
|
---|
1032 | if ( !sid_peek_rid( &sid, &rid ) ) {
|
---|
1033 | d_fprintf(stderr, "Failed to get RID for %s\n", argv[0]);
|
---|
1034 | return -1;
|
---|
1035 | }
|
---|
1036 |
|
---|
1037 | status = pdb_create_builtin_alias( rid );
|
---|
1038 |
|
---|
1039 | if (!NT_STATUS_IS_OK(status)) {
|
---|
1040 | d_fprintf(stderr, "Creating %s failed with %s\n",
|
---|
1041 | argv[0], nt_errstr(status));
|
---|
1042 | return -1;
|
---|
1043 | }
|
---|
1044 |
|
---|
1045 | d_printf("Created BUILTIN group %s with RID %d\n", argv[0], rid);
|
---|
1046 |
|
---|
1047 | return 0;
|
---|
1048 | }
|
---|
1049 |
|
---|
1050 | /*
|
---|
1051 | * Add a group member
|
---|
1052 | */
|
---|
1053 |
|
---|
1054 | static int net_sam_addmem(struct net_context *c, int argc, const char **argv)
|
---|
1055 | {
|
---|
1056 | const char *groupdomain, *groupname, *memberdomain, *membername;
|
---|
1057 | DOM_SID group, member;
|
---|
1058 | enum lsa_SidType grouptype, membertype;
|
---|
1059 | NTSTATUS status;
|
---|
1060 |
|
---|
1061 | if (argc != 2 || c->display_usage) {
|
---|
1062 | d_fprintf(stderr, "usage: net sam addmem <group> <member>\n");
|
---|
1063 | return -1;
|
---|
1064 | }
|
---|
1065 |
|
---|
1066 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
1067 | &groupdomain, &groupname, &group, &grouptype)) {
|
---|
1068 | d_fprintf(stderr, "Could not find group %s\n", argv[0]);
|
---|
1069 | return -1;
|
---|
1070 | }
|
---|
1071 |
|
---|
1072 | /* check to see if the member to be added is a name or a SID */
|
---|
1073 |
|
---|
1074 | if (!lookup_name(talloc_tos(), argv[1], LOOKUP_NAME_LOCAL,
|
---|
1075 | &memberdomain, &membername, &member, &membertype))
|
---|
1076 | {
|
---|
1077 | /* try it as a SID */
|
---|
1078 |
|
---|
1079 | if ( !string_to_sid( &member, argv[1] ) ) {
|
---|
1080 | d_fprintf(stderr, "Could not find member %s\n", argv[1]);
|
---|
1081 | return -1;
|
---|
1082 | }
|
---|
1083 |
|
---|
1084 | if ( !lookup_sid(talloc_tos(), &member, &memberdomain,
|
---|
1085 | &membername, &membertype) )
|
---|
1086 | {
|
---|
1087 | d_fprintf(stderr, "Could not resolve SID %s\n", argv[1]);
|
---|
1088 | return -1;
|
---|
1089 | }
|
---|
1090 | }
|
---|
1091 |
|
---|
1092 | if ((grouptype == SID_NAME_ALIAS) || (grouptype == SID_NAME_WKN_GRP)) {
|
---|
1093 | if ((membertype != SID_NAME_USER) &&
|
---|
1094 | (membertype != SID_NAME_DOM_GRP)) {
|
---|
1095 | d_fprintf(stderr, "%s is a local group, only users "
|
---|
1096 | "and domain groups can be added.\n"
|
---|
1097 | "%s is a %s\n", argv[0], argv[1],
|
---|
1098 | sid_type_lookup(membertype));
|
---|
1099 | return -1;
|
---|
1100 | }
|
---|
1101 | status = pdb_add_aliasmem(&group, &member);
|
---|
1102 |
|
---|
1103 | if (!NT_STATUS_IS_OK(status)) {
|
---|
1104 | d_fprintf(stderr, "Adding local group member failed "
|
---|
1105 | "with %s\n", nt_errstr(status));
|
---|
1106 | return -1;
|
---|
1107 | }
|
---|
1108 | } else {
|
---|
1109 | d_fprintf(stderr, "Can only add members to local groups so "
|
---|
1110 | "far, %s is a %s\n", argv[0],
|
---|
1111 | sid_type_lookup(grouptype));
|
---|
1112 | return -1;
|
---|
1113 | }
|
---|
1114 |
|
---|
1115 | d_printf("Added %s\\%s to %s\\%s\n", memberdomain, membername,
|
---|
1116 | groupdomain, groupname);
|
---|
1117 |
|
---|
1118 | return 0;
|
---|
1119 | }
|
---|
1120 |
|
---|
1121 | /*
|
---|
1122 | * Delete a group member
|
---|
1123 | */
|
---|
1124 |
|
---|
1125 | static int net_sam_delmem(struct net_context *c, int argc, const char **argv)
|
---|
1126 | {
|
---|
1127 | const char *groupdomain, *groupname;
|
---|
1128 | const char *memberdomain = NULL;
|
---|
1129 | const char *membername = NULL;
|
---|
1130 | DOM_SID group, member;
|
---|
1131 | enum lsa_SidType grouptype;
|
---|
1132 | NTSTATUS status;
|
---|
1133 |
|
---|
1134 | if (argc != 2 || c->display_usage) {
|
---|
1135 | d_fprintf(stderr, "usage: net sam delmem <group> <member>\n");
|
---|
1136 | return -1;
|
---|
1137 | }
|
---|
1138 |
|
---|
1139 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
1140 | &groupdomain, &groupname, &group, &grouptype)) {
|
---|
1141 | d_fprintf(stderr, "Could not find group %s\n", argv[0]);
|
---|
1142 | return -1;
|
---|
1143 | }
|
---|
1144 |
|
---|
1145 | if (!lookup_name(talloc_tos(), argv[1], LOOKUP_NAME_LOCAL,
|
---|
1146 | &memberdomain, &membername, &member, NULL)) {
|
---|
1147 | if (!string_to_sid(&member, argv[1])) {
|
---|
1148 | d_fprintf(stderr, "Could not find member %s\n",
|
---|
1149 | argv[1]);
|
---|
1150 | return -1;
|
---|
1151 | }
|
---|
1152 | }
|
---|
1153 |
|
---|
1154 | if ((grouptype == SID_NAME_ALIAS) ||
|
---|
1155 | (grouptype == SID_NAME_WKN_GRP)) {
|
---|
1156 | status = pdb_del_aliasmem(&group, &member);
|
---|
1157 |
|
---|
1158 | if (!NT_STATUS_IS_OK(status)) {
|
---|
1159 | d_fprintf(stderr, "Deleting local group member failed "
|
---|
1160 | "with %s\n", nt_errstr(status));
|
---|
1161 | return -1;
|
---|
1162 | }
|
---|
1163 | } else {
|
---|
1164 | d_fprintf(stderr, "Can only delete members from local groups "
|
---|
1165 | "so far, %s is a %s\n", argv[0],
|
---|
1166 | sid_type_lookup(grouptype));
|
---|
1167 | return -1;
|
---|
1168 | }
|
---|
1169 |
|
---|
1170 | if (membername != NULL) {
|
---|
1171 | d_printf("Deleted %s\\%s from %s\\%s\n",
|
---|
1172 | memberdomain, membername, groupdomain, groupname);
|
---|
1173 | } else {
|
---|
1174 | d_printf("Deleted %s from %s\\%s\n",
|
---|
1175 | sid_string_tos(&member), groupdomain, groupname);
|
---|
1176 | }
|
---|
1177 |
|
---|
1178 | return 0;
|
---|
1179 | }
|
---|
1180 |
|
---|
1181 | /*
|
---|
1182 | * List group members
|
---|
1183 | */
|
---|
1184 |
|
---|
1185 | static int net_sam_listmem(struct net_context *c, int argc, const char **argv)
|
---|
1186 | {
|
---|
1187 | const char *groupdomain, *groupname;
|
---|
1188 | DOM_SID group;
|
---|
1189 | enum lsa_SidType grouptype;
|
---|
1190 | NTSTATUS status;
|
---|
1191 |
|
---|
1192 | if (argc != 1 || c->display_usage) {
|
---|
1193 | d_fprintf(stderr, "usage: net sam listmem <group>\n");
|
---|
1194 | return -1;
|
---|
1195 | }
|
---|
1196 |
|
---|
1197 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
1198 | &groupdomain, &groupname, &group, &grouptype)) {
|
---|
1199 | d_fprintf(stderr, "Could not find group %s\n", argv[0]);
|
---|
1200 | return -1;
|
---|
1201 | }
|
---|
1202 |
|
---|
1203 | if ((grouptype == SID_NAME_ALIAS) ||
|
---|
1204 | (grouptype == SID_NAME_WKN_GRP)) {
|
---|
1205 | DOM_SID *members = NULL;
|
---|
1206 | size_t i, num_members = 0;
|
---|
1207 |
|
---|
1208 | status = pdb_enum_aliasmem(&group, &members, &num_members);
|
---|
1209 |
|
---|
1210 | if (!NT_STATUS_IS_OK(status)) {
|
---|
1211 | d_fprintf(stderr, "Listing group members failed with "
|
---|
1212 | "%s\n", nt_errstr(status));
|
---|
1213 | return -1;
|
---|
1214 | }
|
---|
1215 |
|
---|
1216 | d_printf("%s\\%s has %u members\n", groupdomain, groupname,
|
---|
1217 | (unsigned int)num_members);
|
---|
1218 | for (i=0; i<num_members; i++) {
|
---|
1219 | const char *dom, *name;
|
---|
1220 | if (lookup_sid(talloc_tos(), &members[i],
|
---|
1221 | &dom, &name, NULL)) {
|
---|
1222 | d_printf(" %s\\%s\n", dom, name);
|
---|
1223 | } else {
|
---|
1224 | d_printf(" %s\n", sid_string_tos(&members[i]));
|
---|
1225 | }
|
---|
1226 | }
|
---|
1227 |
|
---|
1228 | TALLOC_FREE(members);
|
---|
1229 | } else {
|
---|
1230 | d_fprintf(stderr, "Can only list local group members so far.\n"
|
---|
1231 | "%s is a %s\n", argv[0], sid_type_lookup(grouptype));
|
---|
1232 | return -1;
|
---|
1233 | }
|
---|
1234 |
|
---|
1235 | return 0;
|
---|
1236 | }
|
---|
1237 |
|
---|
1238 | /*
|
---|
1239 | * Do the listing
|
---|
1240 | */
|
---|
1241 | static int net_sam_do_list(struct net_context *c, int argc, const char **argv,
|
---|
1242 | struct pdb_search *search, const char *what)
|
---|
1243 | {
|
---|
1244 | bool verbose = (argc == 1);
|
---|
1245 |
|
---|
1246 | if ((argc > 1) || c->display_usage ||
|
---|
1247 | ((argc == 1) && !strequal(argv[0], "verbose"))) {
|
---|
1248 | d_fprintf(stderr, "usage: net sam list %s [verbose]\n", what);
|
---|
1249 | return -1;
|
---|
1250 | }
|
---|
1251 |
|
---|
1252 | if (search == NULL) {
|
---|
1253 | d_fprintf(stderr, "Could not start search\n");
|
---|
1254 | return -1;
|
---|
1255 | }
|
---|
1256 |
|
---|
1257 | while (true) {
|
---|
1258 | struct samr_displayentry entry;
|
---|
1259 | if (!search->next_entry(search, &entry)) {
|
---|
1260 | break;
|
---|
1261 | }
|
---|
1262 | if (verbose) {
|
---|
1263 | d_printf("%s:%d:%s\n",
|
---|
1264 | entry.account_name,
|
---|
1265 | entry.rid,
|
---|
1266 | entry.description);
|
---|
1267 | } else {
|
---|
1268 | d_printf("%s\n", entry.account_name);
|
---|
1269 | }
|
---|
1270 | }
|
---|
1271 |
|
---|
1272 | pdb_search_destroy(search);
|
---|
1273 | return 0;
|
---|
1274 | }
|
---|
1275 |
|
---|
1276 | static int net_sam_list_users(struct net_context *c, int argc,
|
---|
1277 | const char **argv)
|
---|
1278 | {
|
---|
1279 | return net_sam_do_list(c, argc, argv, pdb_search_users(ACB_NORMAL),
|
---|
1280 | "users");
|
---|
1281 | }
|
---|
1282 |
|
---|
1283 | static int net_sam_list_groups(struct net_context *c, int argc,
|
---|
1284 | const char **argv)
|
---|
1285 | {
|
---|
1286 | return net_sam_do_list(c, argc, argv, pdb_search_groups(), "groups");
|
---|
1287 | }
|
---|
1288 |
|
---|
1289 | static int net_sam_list_localgroups(struct net_context *c, int argc,
|
---|
1290 | const char **argv)
|
---|
1291 | {
|
---|
1292 | return net_sam_do_list(c, argc, argv,
|
---|
1293 | pdb_search_aliases(get_global_sam_sid()),
|
---|
1294 | "localgroups");
|
---|
1295 | }
|
---|
1296 |
|
---|
1297 | static int net_sam_list_builtin(struct net_context *c, int argc,
|
---|
1298 | const char **argv)
|
---|
1299 | {
|
---|
1300 | return net_sam_do_list(c, argc, argv,
|
---|
1301 | pdb_search_aliases(&global_sid_Builtin),
|
---|
1302 | "builtin");
|
---|
1303 | }
|
---|
1304 |
|
---|
1305 | static int net_sam_list_workstations(struct net_context *c, int argc,
|
---|
1306 | const char **argv)
|
---|
1307 | {
|
---|
1308 | return net_sam_do_list(c, argc, argv,
|
---|
1309 | pdb_search_users(ACB_WSTRUST),
|
---|
1310 | "workstations");
|
---|
1311 | }
|
---|
1312 |
|
---|
1313 | /*
|
---|
1314 | * List stuff
|
---|
1315 | */
|
---|
1316 |
|
---|
1317 | static int net_sam_list(struct net_context *c, int argc, const char **argv)
|
---|
1318 | {
|
---|
1319 | struct functable func[] = {
|
---|
1320 | {
|
---|
1321 | "users",
|
---|
1322 | net_sam_list_users,
|
---|
1323 | NET_TRANSPORT_LOCAL,
|
---|
1324 | "List SAM users",
|
---|
1325 | "net sam list users\n"
|
---|
1326 | " List SAM users"
|
---|
1327 | },
|
---|
1328 | {
|
---|
1329 | "groups",
|
---|
1330 | net_sam_list_groups,
|
---|
1331 | NET_TRANSPORT_LOCAL,
|
---|
1332 | "List SAM groups",
|
---|
1333 | "net sam list groups\n"
|
---|
1334 | " List SAM groups"
|
---|
1335 | },
|
---|
1336 | {
|
---|
1337 | "localgroups",
|
---|
1338 | net_sam_list_localgroups,
|
---|
1339 | NET_TRANSPORT_LOCAL,
|
---|
1340 | "List SAM local groups",
|
---|
1341 | "net sam list localgroups\n"
|
---|
1342 | " List SAM local groups"
|
---|
1343 | },
|
---|
1344 | {
|
---|
1345 | "builtin",
|
---|
1346 | net_sam_list_builtin,
|
---|
1347 | NET_TRANSPORT_LOCAL,
|
---|
1348 | "List builtin groups",
|
---|
1349 | "net sam list builtin\n"
|
---|
1350 | " List builtin groups"
|
---|
1351 | },
|
---|
1352 | {
|
---|
1353 | "workstations",
|
---|
1354 | net_sam_list_workstations,
|
---|
1355 | NET_TRANSPORT_LOCAL,
|
---|
1356 | "List domain member workstations",
|
---|
1357 | "net sam list workstations\n"
|
---|
1358 | " List domain member workstations"
|
---|
1359 | },
|
---|
1360 | {NULL, NULL, 0, NULL, NULL}
|
---|
1361 | };
|
---|
1362 |
|
---|
1363 | return net_run_function(c, argc, argv, "net sam list", func);
|
---|
1364 | }
|
---|
1365 |
|
---|
1366 | /*
|
---|
1367 | * Show details of SAM entries
|
---|
1368 | */
|
---|
1369 |
|
---|
1370 | static int net_sam_show(struct net_context *c, int argc, const char **argv)
|
---|
1371 | {
|
---|
1372 | DOM_SID sid;
|
---|
1373 | enum lsa_SidType type;
|
---|
1374 | const char *dom, *name;
|
---|
1375 |
|
---|
1376 | if (argc != 1 || c->display_usage) {
|
---|
1377 | d_fprintf(stderr, "usage: net sam show <name>\n");
|
---|
1378 | return -1;
|
---|
1379 | }
|
---|
1380 |
|
---|
1381 | if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
|
---|
1382 | &dom, &name, &sid, &type)) {
|
---|
1383 | d_fprintf(stderr, "Could not find name %s\n", argv[0]);
|
---|
1384 | return -1;
|
---|
1385 | }
|
---|
1386 |
|
---|
1387 | d_printf("%s\\%s is a %s with SID %s\n", dom, name,
|
---|
1388 | sid_type_lookup(type), sid_string_tos(&sid));
|
---|
1389 |
|
---|
1390 | return 0;
|
---|
1391 | }
|
---|
1392 |
|
---|
1393 | #ifdef HAVE_LDAP
|
---|
1394 |
|
---|
1395 | /*
|
---|
1396 | * Init an LDAP tree with default users and Groups
|
---|
1397 | * if ldapsam:editposix is enabled
|
---|
1398 | */
|
---|
1399 |
|
---|
1400 | static int net_sam_provision(struct net_context *c, int argc, const char **argv)
|
---|
1401 | {
|
---|
1402 | TALLOC_CTX *tc;
|
---|
1403 | char *ldap_bk;
|
---|
1404 | char *ldap_uri = NULL;
|
---|
1405 | char *p;
|
---|
1406 | struct smbldap_state *ls;
|
---|
1407 | GROUP_MAP gmap;
|
---|
1408 | DOM_SID gsid;
|
---|
1409 | gid_t domusers_gid = -1;
|
---|
1410 | gid_t domadmins_gid = -1;
|
---|
1411 | struct samu *samuser;
|
---|
1412 | struct passwd *pwd;
|
---|
1413 |
|
---|
1414 | if (c->display_usage) {
|
---|
1415 | d_printf("Usage:\n"
|
---|
1416 | "net sam provision\n"
|
---|
1417 | " Init an LDAP tree with default users/groups\n");
|
---|
1418 | return 0;
|
---|
1419 | }
|
---|
1420 |
|
---|
1421 | tc = talloc_new(NULL);
|
---|
1422 | if (!tc) {
|
---|
1423 | d_fprintf(stderr, "Out of Memory!\n");
|
---|
1424 | return -1;
|
---|
1425 | }
|
---|
1426 |
|
---|
1427 | if ((ldap_bk = talloc_strdup(tc, lp_passdb_backend())) == NULL) {
|
---|
1428 | d_fprintf(stderr, "talloc failed\n");
|
---|
1429 | talloc_free(tc);
|
---|
1430 | return -1;
|
---|
1431 | }
|
---|
1432 | p = strchr(ldap_bk, ':');
|
---|
1433 | if (p) {
|
---|
1434 | *p = 0;
|
---|
1435 | ldap_uri = talloc_strdup(tc, p+1);
|
---|
1436 | trim_char(ldap_uri, ' ', ' ');
|
---|
1437 | }
|
---|
1438 |
|
---|
1439 | trim_char(ldap_bk, ' ', ' ');
|
---|
1440 |
|
---|
1441 | if (strcmp(ldap_bk, "ldapsam") != 0) {
|
---|
1442 | d_fprintf(stderr, "Provisioning works only with ldapsam backend\n");
|
---|
1443 | goto failed;
|
---|
1444 | }
|
---|
1445 |
|
---|
1446 | if (!lp_parm_bool(-1, "ldapsam", "trusted", false) ||
|
---|
1447 | !lp_parm_bool(-1, "ldapsam", "editposix", false)) {
|
---|
1448 |
|
---|
1449 | d_fprintf(stderr, "Provisioning works only if ldapsam:trusted"
|
---|
1450 | " and ldapsam:editposix are enabled.\n");
|
---|
1451 | goto failed;
|
---|
1452 | }
|
---|
1453 |
|
---|
1454 | if (!winbind_ping()) {
|
---|
1455 | d_fprintf(stderr, "winbind seems not to run. Provisioning "
|
---|
1456 | "LDAP only works when winbind runs.\n");
|
---|
1457 | goto failed;
|
---|
1458 | }
|
---|
1459 |
|
---|
1460 | if (!NT_STATUS_IS_OK(smbldap_init(tc, NULL, ldap_uri, &ls))) {
|
---|
1461 | d_fprintf(stderr, "Unable to connect to the LDAP server.\n");
|
---|
1462 | goto failed;
|
---|
1463 | }
|
---|
1464 |
|
---|
1465 | d_printf("Checking for Domain Users group.\n");
|
---|
1466 |
|
---|
1467 | sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS);
|
---|
1468 |
|
---|
1469 | if (!pdb_getgrsid(&gmap, gsid)) {
|
---|
1470 | LDAPMod **mods = NULL;
|
---|
1471 | char *dn;
|
---|
1472 | char *uname;
|
---|
1473 | char *wname;
|
---|
1474 | char *gidstr;
|
---|
1475 | char *gtype;
|
---|
1476 | int rc;
|
---|
1477 |
|
---|
1478 | d_printf("Adding the Domain Users group.\n");
|
---|
1479 |
|
---|
1480 | /* lets allocate a new groupid for this group */
|
---|
1481 | if (!winbind_allocate_gid(&domusers_gid)) {
|
---|
1482 | d_fprintf(stderr, "Unable to allocate a new gid to create Domain Users group!\n");
|
---|
1483 | goto domu_done;
|
---|
1484 | }
|
---|
1485 |
|
---|
1486 | uname = talloc_strdup(tc, "domusers");
|
---|
1487 | wname = talloc_strdup(tc, "Domain Users");
|
---|
1488 | dn = talloc_asprintf(tc, "cn=%s,%s", "domusers", lp_ldap_group_suffix());
|
---|
1489 | gidstr = talloc_asprintf(tc, "%d", domusers_gid);
|
---|
1490 | gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
|
---|
1491 |
|
---|
1492 | if (!uname || !wname || !dn || !gidstr || !gtype) {
|
---|
1493 | d_fprintf(stderr, "Out of Memory!\n");
|
---|
1494 | goto failed;
|
---|
1495 | }
|
---|
1496 |
|
---|
1497 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXGROUP);
|
---|
1498 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
|
---|
1499 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
|
---|
1500 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
|
---|
1501 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
|
---|
1502 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid",
|
---|
1503 | sid_string_talloc(tc, &gsid));
|
---|
1504 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
|
---|
1505 |
|
---|
1506 | talloc_autofree_ldapmod(tc, mods);
|
---|
1507 |
|
---|
1508 | rc = smbldap_add(ls, dn, mods);
|
---|
1509 |
|
---|
1510 | if (rc != LDAP_SUCCESS) {
|
---|
1511 | d_fprintf(stderr, "Failed to add Domain Users group to ldap directory\n");
|
---|
1512 | }
|
---|
1513 | } else {
|
---|
1514 | domusers_gid = gmap.gid;
|
---|
1515 | d_printf("found!\n");
|
---|
1516 | }
|
---|
1517 |
|
---|
1518 | domu_done:
|
---|
1519 |
|
---|
1520 | d_printf("Checking for Domain Admins group.\n");
|
---|
1521 |
|
---|
1522 | sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_ADMINS);
|
---|
1523 |
|
---|
1524 | if (!pdb_getgrsid(&gmap, gsid)) {
|
---|
1525 | LDAPMod **mods = NULL;
|
---|
1526 | char *dn;
|
---|
1527 | char *uname;
|
---|
1528 | char *wname;
|
---|
1529 | char *gidstr;
|
---|
1530 | char *gtype;
|
---|
1531 | int rc;
|
---|
1532 |
|
---|
1533 | d_printf("Adding the Domain Admins group.\n");
|
---|
1534 |
|
---|
1535 | /* lets allocate a new groupid for this group */
|
---|
1536 | if (!winbind_allocate_gid(&domadmins_gid)) {
|
---|
1537 | d_fprintf(stderr, "Unable to allocate a new gid to create Domain Admins group!\n");
|
---|
1538 | goto doma_done;
|
---|
1539 | }
|
---|
1540 |
|
---|
1541 | uname = talloc_strdup(tc, "domadmins");
|
---|
1542 | wname = talloc_strdup(tc, "Domain Admins");
|
---|
1543 | dn = talloc_asprintf(tc, "cn=%s,%s", "domadmins", lp_ldap_group_suffix());
|
---|
1544 | gidstr = talloc_asprintf(tc, "%d", domadmins_gid);
|
---|
1545 | gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
|
---|
1546 |
|
---|
1547 | if (!uname || !wname || !dn || !gidstr || !gtype) {
|
---|
1548 | d_fprintf(stderr, "Out of Memory!\n");
|
---|
1549 | goto failed;
|
---|
1550 | }
|
---|
1551 |
|
---|
1552 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXGROUP);
|
---|
1553 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
|
---|
1554 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
|
---|
1555 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
|
---|
1556 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
|
---|
1557 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid",
|
---|
1558 | sid_string_talloc(tc, &gsid));
|
---|
1559 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
|
---|
1560 |
|
---|
1561 | talloc_autofree_ldapmod(tc, mods);
|
---|
1562 |
|
---|
1563 | rc = smbldap_add(ls, dn, mods);
|
---|
1564 |
|
---|
1565 | if (rc != LDAP_SUCCESS) {
|
---|
1566 | d_fprintf(stderr, "Failed to add Domain Admins group to ldap directory\n");
|
---|
1567 | }
|
---|
1568 | } else {
|
---|
1569 | domadmins_gid = gmap.gid;
|
---|
1570 | d_printf("found!\n");
|
---|
1571 | }
|
---|
1572 |
|
---|
1573 | doma_done:
|
---|
1574 |
|
---|
1575 | d_printf("Check for Administrator account.\n");
|
---|
1576 |
|
---|
1577 | samuser = samu_new(tc);
|
---|
1578 | if (!samuser) {
|
---|
1579 | d_fprintf(stderr, "Out of Memory!\n");
|
---|
1580 | goto failed;
|
---|
1581 | }
|
---|
1582 |
|
---|
1583 | if (!pdb_getsampwnam(samuser, "Administrator")) {
|
---|
1584 | LDAPMod **mods = NULL;
|
---|
1585 | DOM_SID sid;
|
---|
1586 | char *dn;
|
---|
1587 | char *name;
|
---|
1588 | char *uidstr;
|
---|
1589 | char *gidstr;
|
---|
1590 | char *shell;
|
---|
1591 | char *dir;
|
---|
1592 | uid_t uid;
|
---|
1593 | int rc;
|
---|
1594 |
|
---|
1595 | d_printf("Adding the Administrator user.\n");
|
---|
1596 |
|
---|
1597 | if (domadmins_gid == -1) {
|
---|
1598 | d_fprintf(stderr, "Can't create Administrator user, Domain Admins group not available!\n");
|
---|
1599 | goto done;
|
---|
1600 | }
|
---|
1601 | if (!winbind_allocate_uid(&uid)) {
|
---|
1602 | d_fprintf(stderr, "Unable to allocate a new uid to create the Administrator user!\n");
|
---|
1603 | goto done;
|
---|
1604 | }
|
---|
1605 | name = talloc_strdup(tc, "Administrator");
|
---|
1606 | dn = talloc_asprintf(tc, "uid=Administrator,%s", lp_ldap_user_suffix());
|
---|
1607 | uidstr = talloc_asprintf(tc, "%d", uid);
|
---|
1608 | gidstr = talloc_asprintf(tc, "%d", domadmins_gid);
|
---|
1609 | dir = talloc_sub_specified(tc, lp_template_homedir(),
|
---|
1610 | "Administrator",
|
---|
1611 | get_global_sam_name(),
|
---|
1612 | uid, domadmins_gid);
|
---|
1613 | shell = talloc_sub_specified(tc, lp_template_shell(),
|
---|
1614 | "Administrator",
|
---|
1615 | get_global_sam_name(),
|
---|
1616 | uid, domadmins_gid);
|
---|
1617 |
|
---|
1618 | if (!name || !dn || !uidstr || !gidstr || !dir || !shell) {
|
---|
1619 | d_fprintf(stderr, "Out of Memory!\n");
|
---|
1620 | goto failed;
|
---|
1621 | }
|
---|
1622 |
|
---|
1623 | sid_compose(&sid, get_global_sam_sid(), DOMAIN_USER_RID_ADMIN);
|
---|
1624 |
|
---|
1625 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
|
---|
1626 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
|
---|
1627 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
|
---|
1628 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "uid", name);
|
---|
1629 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
|
---|
1630 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
|
---|
1631 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
|
---|
1632 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
|
---|
1633 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", dir);
|
---|
1634 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
|
---|
1635 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSID",
|
---|
1636 | sid_string_talloc(tc, &sid));
|
---|
1637 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaAcctFlags",
|
---|
1638 | pdb_encode_acct_ctrl(ACB_NORMAL|ACB_DISABLED,
|
---|
1639 | NEW_PW_FORMAT_SPACE_PADDED_LEN));
|
---|
1640 |
|
---|
1641 | talloc_autofree_ldapmod(tc, mods);
|
---|
1642 |
|
---|
1643 | rc = smbldap_add(ls, dn, mods);
|
---|
1644 |
|
---|
1645 | if (rc != LDAP_SUCCESS) {
|
---|
1646 | d_fprintf(stderr, "Failed to add Administrator user to ldap directory\n");
|
---|
1647 | }
|
---|
1648 | } else {
|
---|
1649 | d_printf("found!\n");
|
---|
1650 | }
|
---|
1651 |
|
---|
1652 | d_printf("Checking for Guest user.\n");
|
---|
1653 |
|
---|
1654 | samuser = samu_new(tc);
|
---|
1655 | if (!samuser) {
|
---|
1656 | d_fprintf(stderr, "Out of Memory!\n");
|
---|
1657 | goto failed;
|
---|
1658 | }
|
---|
1659 |
|
---|
1660 | if (!pdb_getsampwnam(samuser, lp_guestaccount())) {
|
---|
1661 | LDAPMod **mods = NULL;
|
---|
1662 | DOM_SID sid;
|
---|
1663 | char *dn;
|
---|
1664 | char *uidstr;
|
---|
1665 | char *gidstr;
|
---|
1666 | int rc;
|
---|
1667 |
|
---|
1668 | d_printf("Adding the Guest user.\n");
|
---|
1669 |
|
---|
1670 | pwd = getpwnam_alloc(tc, lp_guestaccount());
|
---|
1671 |
|
---|
1672 | if (!pwd) {
|
---|
1673 | if (domusers_gid == -1) {
|
---|
1674 | d_fprintf(stderr, "Can't create Guest user, Domain Users group not available!\n");
|
---|
1675 | goto done;
|
---|
1676 | }
|
---|
1677 | if ((pwd = talloc(tc, struct passwd)) == NULL) {
|
---|
1678 | d_fprintf(stderr, "talloc failed\n");
|
---|
1679 | goto done;
|
---|
1680 | }
|
---|
1681 | pwd->pw_name = talloc_strdup(pwd, lp_guestaccount());
|
---|
1682 | if (!winbind_allocate_uid(&(pwd->pw_uid))) {
|
---|
1683 | d_fprintf(stderr, "Unable to allocate a new uid to create the Guest user!\n");
|
---|
1684 | goto done;
|
---|
1685 | }
|
---|
1686 | pwd->pw_gid = domusers_gid;
|
---|
1687 | pwd->pw_dir = talloc_strdup(tc, "/");
|
---|
1688 | pwd->pw_shell = talloc_strdup(tc, "/bin/false");
|
---|
1689 | if (!pwd->pw_dir || !pwd->pw_shell) {
|
---|
1690 | d_fprintf(stderr, "Out of Memory!\n");
|
---|
1691 | goto failed;
|
---|
1692 | }
|
---|
1693 | }
|
---|
1694 |
|
---|
1695 | sid_compose(&sid, get_global_sam_sid(), DOMAIN_USER_RID_GUEST);
|
---|
1696 |
|
---|
1697 | dn = talloc_asprintf(tc, "uid=%s,%s", pwd->pw_name, lp_ldap_user_suffix ());
|
---|
1698 | uidstr = talloc_asprintf(tc, "%d", pwd->pw_uid);
|
---|
1699 | gidstr = talloc_asprintf(tc, "%d", pwd->pw_gid);
|
---|
1700 | if (!dn || !uidstr || !gidstr) {
|
---|
1701 | d_fprintf(stderr, "Out of Memory!\n");
|
---|
1702 | goto failed;
|
---|
1703 | }
|
---|
1704 |
|
---|
1705 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
|
---|
1706 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
|
---|
1707 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
|
---|
1708 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "uid", pwd->pw_name);
|
---|
1709 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", pwd->pw_name);
|
---|
1710 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", pwd->pw_name);
|
---|
1711 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
|
---|
1712 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
|
---|
1713 | if ((pwd->pw_dir != NULL) && (pwd->pw_dir[0] != '\0')) {
|
---|
1714 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", pwd->pw_dir);
|
---|
1715 | }
|
---|
1716 | if ((pwd->pw_shell != NULL) && (pwd->pw_shell[0] != '\0')) {
|
---|
1717 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", pwd->pw_shell);
|
---|
1718 | }
|
---|
1719 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSID",
|
---|
1720 | sid_string_talloc(tc, &sid));
|
---|
1721 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaAcctFlags",
|
---|
1722 | pdb_encode_acct_ctrl(ACB_NORMAL|ACB_DISABLED,
|
---|
1723 | NEW_PW_FORMAT_SPACE_PADDED_LEN));
|
---|
1724 |
|
---|
1725 | talloc_autofree_ldapmod(tc, mods);
|
---|
1726 |
|
---|
1727 | rc = smbldap_add(ls, dn, mods);
|
---|
1728 |
|
---|
1729 | if (rc != LDAP_SUCCESS) {
|
---|
1730 | d_fprintf(stderr, "Failed to add Guest user to ldap directory\n");
|
---|
1731 | }
|
---|
1732 | } else {
|
---|
1733 | d_printf("found!\n");
|
---|
1734 | }
|
---|
1735 |
|
---|
1736 | d_printf("Checking Guest's group.\n");
|
---|
1737 |
|
---|
1738 | pwd = getpwnam_alloc(talloc_autofree_context(), lp_guestaccount());
|
---|
1739 | if (!pwd) {
|
---|
1740 | d_fprintf(stderr, "Failed to find just created Guest account!\n"
|
---|
1741 | " Is nss properly configured?!\n");
|
---|
1742 | goto failed;
|
---|
1743 | }
|
---|
1744 |
|
---|
1745 | if (pwd->pw_gid == domusers_gid) {
|
---|
1746 | d_printf("found!\n");
|
---|
1747 | goto done;
|
---|
1748 | }
|
---|
1749 |
|
---|
1750 | if (!pdb_getgrgid(&gmap, pwd->pw_gid)) {
|
---|
1751 | LDAPMod **mods = NULL;
|
---|
1752 | char *dn;
|
---|
1753 | char *uname;
|
---|
1754 | char *wname;
|
---|
1755 | char *gidstr;
|
---|
1756 | char *gtype;
|
---|
1757 | int rc;
|
---|
1758 |
|
---|
1759 | d_printf("Adding the Domain Guests group.\n");
|
---|
1760 |
|
---|
1761 | uname = talloc_strdup(tc, "domguests");
|
---|
1762 | wname = talloc_strdup(tc, "Domain Guests");
|
---|
1763 | dn = talloc_asprintf(tc, "cn=%s,%s", "domguests", lp_ldap_group_suffix());
|
---|
1764 | gidstr = talloc_asprintf(tc, "%d", pwd->pw_gid);
|
---|
1765 | gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
|
---|
1766 |
|
---|
1767 | if (!uname || !wname || !dn || !gidstr || !gtype) {
|
---|
1768 | d_fprintf(stderr, "Out of Memory!\n");
|
---|
1769 | goto failed;
|
---|
1770 | }
|
---|
1771 |
|
---|
1772 | sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_GUESTS);
|
---|
1773 |
|
---|
1774 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXGROUP);
|
---|
1775 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
|
---|
1776 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
|
---|
1777 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
|
---|
1778 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
|
---|
1779 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid",
|
---|
1780 | sid_string_talloc(tc, &gsid));
|
---|
1781 | smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
|
---|
1782 |
|
---|
1783 | talloc_autofree_ldapmod(tc, mods);
|
---|
1784 |
|
---|
1785 | rc = smbldap_add(ls, dn, mods);
|
---|
1786 |
|
---|
1787 | if (rc != LDAP_SUCCESS) {
|
---|
1788 | d_fprintf(stderr, "Failed to add Domain Guests group to ldap directory\n");
|
---|
1789 | }
|
---|
1790 | } else {
|
---|
1791 | d_printf("found!\n");
|
---|
1792 | }
|
---|
1793 |
|
---|
1794 |
|
---|
1795 | done:
|
---|
1796 | talloc_free(tc);
|
---|
1797 | return 0;
|
---|
1798 |
|
---|
1799 | failed:
|
---|
1800 | talloc_free(tc);
|
---|
1801 | return -1;
|
---|
1802 | }
|
---|
1803 |
|
---|
1804 | #endif
|
---|
1805 |
|
---|
1806 | /***********************************************************
|
---|
1807 | migrated functionality from smbgroupedit
|
---|
1808 | **********************************************************/
|
---|
1809 | int net_sam(struct net_context *c, int argc, const char **argv)
|
---|
1810 | {
|
---|
1811 | struct functable func[] = {
|
---|
1812 | {
|
---|
1813 | "createbuiltingroup",
|
---|
1814 | net_sam_createbuiltingroup,
|
---|
1815 | NET_TRANSPORT_LOCAL,
|
---|
1816 | "Create a new BUILTIN group",
|
---|
1817 | "net sam createbuiltingroup\n"
|
---|
1818 | " Create a new BUILTIN group"
|
---|
1819 | },
|
---|
1820 | {
|
---|
1821 | "createlocalgroup",
|
---|
1822 | net_sam_createlocalgroup,
|
---|
1823 | NET_TRANSPORT_LOCAL,
|
---|
1824 | "Create a new local group",
|
---|
1825 | "net sam createlocalgroup\n"
|
---|
1826 | " Create a new local group"
|
---|
1827 | },
|
---|
1828 | {
|
---|
1829 | "deletelocalgroup",
|
---|
1830 | net_sam_deletelocalgroup,
|
---|
1831 | NET_TRANSPORT_LOCAL,
|
---|
1832 | "Delete an existing local group",
|
---|
1833 | "net sam deletelocalgroup\n"
|
---|
1834 | " Delete an existing local group"
|
---|
1835 | },
|
---|
1836 | {
|
---|
1837 | "mapunixgroup",
|
---|
1838 | net_sam_mapunixgroup,
|
---|
1839 | NET_TRANSPORT_LOCAL,
|
---|
1840 | "Map a unix group to a domain group",
|
---|
1841 | "net sam mapunixgroup\n"
|
---|
1842 | " Map a unix group to a domain group"
|
---|
1843 | },
|
---|
1844 | {
|
---|
1845 | "unmapunixgroup",
|
---|
1846 | net_sam_unmapunixgroup,
|
---|
1847 | NET_TRANSPORT_LOCAL,
|
---|
1848 | "Remove a group mapping of an unix group to a domain "
|
---|
1849 | "group",
|
---|
1850 | "net sam unmapunixgroup\n"
|
---|
1851 | " Remove a group mapping of an unix group to a "
|
---|
1852 | "domain group"
|
---|
1853 | },
|
---|
1854 | {
|
---|
1855 | "addmem",
|
---|
1856 | net_sam_addmem,
|
---|
1857 | NET_TRANSPORT_LOCAL,
|
---|
1858 | "Add a member to a group",
|
---|
1859 | "net sam addmem\n"
|
---|
1860 | " Add a member to a group"
|
---|
1861 | },
|
---|
1862 | {
|
---|
1863 | "delmem",
|
---|
1864 | net_sam_delmem,
|
---|
1865 | NET_TRANSPORT_LOCAL,
|
---|
1866 | "Delete a member from a group",
|
---|
1867 | "net sam delmem\n"
|
---|
1868 | " Delete a member from a group"
|
---|
1869 | },
|
---|
1870 | {
|
---|
1871 | "listmem",
|
---|
1872 | net_sam_listmem,
|
---|
1873 | NET_TRANSPORT_LOCAL,
|
---|
1874 | "List group members",
|
---|
1875 | "net sam listmem\n"
|
---|
1876 | " List group members"
|
---|
1877 | },
|
---|
1878 | {
|
---|
1879 | "list",
|
---|
1880 | net_sam_list,
|
---|
1881 | NET_TRANSPORT_LOCAL,
|
---|
1882 | "List users, groups and local groups",
|
---|
1883 | "net sam list\n"
|
---|
1884 | " List users, groups and local groups"
|
---|
1885 | },
|
---|
1886 | {
|
---|
1887 | "show",
|
---|
1888 | net_sam_show,
|
---|
1889 | NET_TRANSPORT_LOCAL,
|
---|
1890 | "Show details of a SAM entry",
|
---|
1891 | "net sam show\n"
|
---|
1892 | " Show details of a SAM entry"
|
---|
1893 | },
|
---|
1894 | {
|
---|
1895 | "set",
|
---|
1896 | net_sam_set,
|
---|
1897 | NET_TRANSPORT_LOCAL,
|
---|
1898 | "Set details of a SAM account",
|
---|
1899 | "net sam set\n"
|
---|
1900 | " Set details of a SAM account"
|
---|
1901 | },
|
---|
1902 | {
|
---|
1903 | "policy",
|
---|
1904 | net_sam_policy,
|
---|
1905 | NET_TRANSPORT_LOCAL,
|
---|
1906 | "Set account policies",
|
---|
1907 | "net sam policy\n"
|
---|
1908 | " Set account policies"
|
---|
1909 | },
|
---|
1910 | {
|
---|
1911 | "rights",
|
---|
1912 | net_sam_rights,
|
---|
1913 | NET_TRANSPORT_LOCAL,
|
---|
1914 | "Manipulate user privileges",
|
---|
1915 | "net sam rights\n"
|
---|
1916 | " Manipulate user privileges"
|
---|
1917 | },
|
---|
1918 | #ifdef HAVE_LDAP
|
---|
1919 | {
|
---|
1920 | "provision",
|
---|
1921 | net_sam_provision,
|
---|
1922 | NET_TRANSPORT_LOCAL,
|
---|
1923 | "Provision a clean user database",
|
---|
1924 | "net sam privison\n"
|
---|
1925 | " Provision a clear user database"
|
---|
1926 | },
|
---|
1927 | #endif
|
---|
1928 | {NULL, NULL, 0, NULL, NULL}
|
---|
1929 | };
|
---|
1930 |
|
---|
1931 | if (getuid() != 0) {
|
---|
1932 | d_fprintf(stderr, "You are not root, most things won't "
|
---|
1933 | "work\n");
|
---|
1934 | }
|
---|
1935 |
|
---|
1936 | return net_run_function(c, argc, argv, "net sam", func);
|
---|
1937 | }
|
---|
1938 |
|
---|