2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Jean François Micouleau 1998-2001.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern DOM_SID global_sam_sid;
26 static TDB_CONTEXT *tdb; /* used for driver files */
28 #define DATABASE_VERSION_V1 1 /* native byte format. */
29 #define DATABASE_VERSION_V2 2 /* le format. */
31 #define GROUP_PREFIX "UNIXGROUP/"
34 {SE_PRIV_NONE, "no_privs", "No privilege" }, /* this one MUST be first */
35 {SE_PRIV_ADD_MACHINES, "SeMachineAccountPrivilege", "Add workstations to the domain" },
36 {SE_PRIV_SEC_PRIV, "SeSecurityPrivilege", "Manage the audit logs" },
37 {SE_PRIV_TAKE_OWNER, "SeTakeOwnershipPrivilege", "Take ownership of file" },
38 {SE_PRIV_ADD_USERS, "SaAddUsers", "Add users to the domain - Samba" },
39 {SE_PRIV_PRINT_OPERATOR, "SaPrintOp", "Add or remove printers - Samba" },
40 {SE_PRIV_ALL, "SaAllPrivs", "all privileges" }
44 { 2, "SeCreateTokenPrivilege" },
45 { 3, "SeAssignPrimaryTokenPrivilege" },
46 { 4, "SeLockMemoryPrivilege" },
47 { 5, "SeIncreaseQuotaPrivilege" },
48 { 6, "SeMachineAccountPrivilege" },
49 { 7, "SeTcbPrivilege" },
50 { 8, "SeSecurityPrivilege" },
51 { 9, "SeTakeOwnershipPrivilege" },
52 { 10, "SeLoadDriverPrivilege" },
53 { 11, "SeSystemProfilePrivilege" },
54 { 12, "SeSystemtimePrivilege" },
55 { 13, "SeProfileSingleProcessPrivilege" },
56 { 14, "SeIncreaseBasePriorityPrivilege" },
57 { 15, "SeCreatePagefilePrivilege" },
58 { 16, "SeCreatePermanentPrivilege" },
59 { 17, "SeBackupPrivilege" },
60 { 18, "SeRestorePrivilege" },
61 { 19, "SeShutdownPrivilege" },
62 { 20, "SeDebugPrivilege" },
63 { 21, "SeAuditPrivilege" },
64 { 22, "SeSystemEnvironmentPrivilege" },
65 { 23, "SeChangeNotifyPrivilege" },
66 { 24, "SeRemoteShutdownPrivilege" },
67 { 25, "SeUndockPrivilege" },
68 { 26, "SeSyncAgentPrivilege" },
69 { 27, "SeEnableDelegationPrivilege" },
74 * Those are not really privileges like the other ones.
75 * They are handled in a special case and called
79 * SeUnsolicitedInputPrivilege
82 * SeInteractiveLogonRight
83 * SeDenyInteractiveLogonRight
84 * SeDenyNetworkLogonRight
85 * SeDenyBatchLogonRight
86 * SeDenyBatchLogonRight
90 /****************************************************************************
91 check if the user has the required privilege.
92 ****************************************************************************/
93 static BOOL se_priv_access_check(NT_USER_TOKEN *token, uint32 privilege)
95 /* no token, no privilege */
99 if ((token->privilege & privilege)==privilege)
106 /****************************************************************************
107 dump the mapping group mapping to a text file
108 ****************************************************************************/
109 char *decode_sid_name_use(fstring group, enum SID_NAME_USE name_use)
111 static fstring group_type;
115 fstrcpy(group_type,"User");
117 case SID_NAME_DOM_GRP:
118 fstrcpy(group_type,"Domain group");
120 case SID_NAME_DOMAIN:
121 fstrcpy(group_type,"Domain");
124 fstrcpy(group_type,"Local group");
126 case SID_NAME_WKN_GRP:
127 fstrcpy(group_type,"Builtin group");
129 case SID_NAME_DELETED:
130 fstrcpy(group_type,"Deleted");
132 case SID_NAME_INVALID:
133 fstrcpy(group_type,"Invalid");
135 case SID_NAME_UNKNOWN:
137 fstrcpy(group_type,"Unknown type");
141 fstrcpy(group, group_type);
145 /****************************************************************************
146 initialise first time the mapping list - called from init_group_mapping()
147 ****************************************************************************/
148 static BOOL default_group_mapping(void)
158 PRIVILEGE_SET privilege_none;
159 PRIVILEGE_SET privilege_all;
160 PRIVILEGE_SET privilege_print_op;
162 init_privilege(&privilege_none);
163 init_privilege(&privilege_all);
164 init_privilege(&privilege_print_op);
168 set.luid.low=SE_PRIV_PRINT_OPERATOR;
169 add_privilege(&privilege_print_op, set);
171 add_all_privilege(&privilege_all);
173 /* Add the Wellknown groups */
175 add_initial_entry(-1, "S-1-5-32-544", SID_NAME_ALIAS, "Administrators", "", privilege_all, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
176 add_initial_entry(-1, "S-1-5-32-545", SID_NAME_ALIAS, "Users", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
177 add_initial_entry(-1, "S-1-5-32-546", SID_NAME_ALIAS, "Guests", "", privilege_none, PR_ACCESS_FROM_NETWORK);
178 add_initial_entry(-1, "S-1-5-32-547", SID_NAME_ALIAS, "Power Users", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
180 add_initial_entry(-1, "S-1-5-32-548", SID_NAME_ALIAS, "Account Operators", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
181 add_initial_entry(-1, "S-1-5-32-549", SID_NAME_ALIAS, "System Operators", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
182 add_initial_entry(-1, "S-1-5-32-550", SID_NAME_ALIAS, "Print Operators", "", privilege_print_op, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
183 add_initial_entry(-1, "S-1-5-32-551", SID_NAME_ALIAS, "Backup Operators", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
185 add_initial_entry(-1, "S-1-5-32-552", SID_NAME_ALIAS, "Replicators", "", privilege_none, PR_ACCESS_FROM_NETWORK);
187 /* Add the defaults domain groups */
189 sid_copy(&sid_admins, &global_sam_sid);
190 sid_append_rid(&sid_admins, DOMAIN_GROUP_RID_ADMINS);
191 sid_to_string(str_admins, &sid_admins);
192 add_initial_entry(-1, str_admins, SID_NAME_DOM_GRP, "Domain Admins", "", privilege_all, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
194 sid_copy(&sid_users, &global_sam_sid);
195 sid_append_rid(&sid_users, DOMAIN_GROUP_RID_USERS);
196 sid_to_string(str_users, &sid_users);
197 add_initial_entry(-1, str_users, SID_NAME_DOM_GRP, "Domain Users", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
199 sid_copy(&sid_guests, &global_sam_sid);
200 sid_append_rid(&sid_guests, DOMAIN_GROUP_RID_GUESTS);
201 sid_to_string(str_guests, &sid_guests);
202 add_initial_entry(-1, str_guests, SID_NAME_DOM_GRP, "Domain Guests", "", privilege_none, PR_ACCESS_FROM_NETWORK);
207 /****************************************************************************
208 Open the group mapping tdb.
209 ****************************************************************************/
211 static BOOL init_group_mapping(void)
213 static pid_t local_pid;
214 char *vstring = "INFO/version";
217 if (tdb && local_pid == sys_getpid())
219 tdb = tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
221 DEBUG(0,("Failed to open group mapping database\n"));
225 local_pid = sys_getpid();
227 /* handle a Samba upgrade */
228 tdb_lock_bystring(tdb, vstring);
230 /* Cope with byte-reversed older versions of the db. */
231 vers_id = tdb_fetch_int32(tdb, vstring);
232 if ((vers_id == DATABASE_VERSION_V1) || (IREV(vers_id) == DATABASE_VERSION_V1)) {
233 /* Written on a bigendian machine with old fetch_int code. Save as le. */
234 tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
235 vers_id = DATABASE_VERSION_V2;
238 if (vers_id != DATABASE_VERSION_V2) {
239 tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
240 tdb_store_int32(tdb, vstring, DATABASE_VERSION_V2);
243 tdb_unlock_bystring(tdb, vstring);
245 /* write a list of default groups */
246 if(!default_group_mapping())
252 /****************************************************************************
253 ****************************************************************************/
254 BOOL add_mapping_entry(GROUP_MAP *map, int flag)
258 fstring string_sid="";
263 if(!init_group_mapping()) {
264 DEBUG(0,("failed to initialize group mapping"));
268 sid_to_string(string_sid, &map->sid);
270 len = tdb_pack(buf, sizeof(buf), "ddffd",
271 map->gid, map->sid_name_use, map->nt_name, map->comment, map->systemaccount);
273 /* write the privilege list in the TDB database */
276 len += tdb_pack(buf+len, sizeof(buf)-len, "d", set->count);
277 for (i=0; i<set->count; i++)
278 len += tdb_pack(buf+len, sizeof(buf)-len, "ddd",
279 set->set[i].luid.low, set->set[i].luid.high, set->set[i].attr);
281 if (len > sizeof(buf))
284 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
286 kbuf.dsize = strlen(key)+1;
290 if (tdb_store(tdb, kbuf, dbuf, flag) != 0) return False;
295 /****************************************************************************
296 initialise first time the mapping list
297 ****************************************************************************/
298 BOOL add_initial_entry(gid_t gid, fstring sid, enum SID_NAME_USE sid_name_use,
299 fstring nt_name, fstring comment, PRIVILEGE_SET priv_set, uint32 systemaccount)
303 if(!init_group_mapping()) {
304 DEBUG(0,("failed to initialize group mapping"));
309 string_to_sid(&map.sid, sid);
310 map.sid_name_use=sid_name_use;
311 fstrcpy(map.nt_name, nt_name);
312 fstrcpy(map.comment, comment);
313 map.systemaccount=systemaccount;
315 map.priv_set.count=priv_set.count;
316 map.priv_set.set=priv_set.set;
318 add_mapping_entry(&map, TDB_INSERT);
323 /****************************************************************************
324 initialise a privilege list
325 ****************************************************************************/
326 void init_privilege(PRIVILEGE_SET *priv_set)
333 /****************************************************************************
334 free a privilege list
335 ****************************************************************************/
336 BOOL free_privilege(PRIVILEGE_SET *priv_set)
338 if (priv_set->count==0) {
339 DEBUG(100,("free_privilege: count=0, nothing to clear ?\n"));
343 if (priv_set->set==NULL) {
344 DEBUG(0,("free_privilege: list ptr is NULL, very strange !\n"));
348 safe_free(priv_set->set);
356 /****************************************************************************
357 add a privilege to a privilege array
358 ****************************************************************************/
359 BOOL add_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
363 /* check if the privilege is not already in the list */
364 if (check_priv_in_privilege(priv_set, set))
367 /* we can allocate memory to add the new privilege */
369 new_set=(LUID_ATTR *)Realloc(priv_set->set, (priv_set->count+1)*(sizeof(LUID_ATTR)));
371 DEBUG(0,("add_privilege: could not Realloc memory to add a new privilege\n"));
375 new_set[priv_set->count].luid.high=set.luid.high;
376 new_set[priv_set->count].luid.low=set.luid.low;
377 new_set[priv_set->count].attr=set.attr;
380 priv_set->set=new_set;
385 /****************************************************************************
386 add all the privileges to a privilege array
387 ****************************************************************************/
388 BOOL add_all_privilege(PRIVILEGE_SET *priv_set)
395 set.luid.low=SE_PRIV_ADD_USERS;
396 add_privilege(priv_set, set);
398 set.luid.low=SE_PRIV_ADD_MACHINES;
399 add_privilege(priv_set, set);
401 set.luid.low=SE_PRIV_PRINT_OPERATOR;
402 add_privilege(priv_set, set);
407 /****************************************************************************
408 check if the privilege list is empty
409 ****************************************************************************/
410 BOOL check_empty_privilege(PRIVILEGE_SET *priv_set)
412 return (priv_set->count == 0);
415 /****************************************************************************
416 check if the privilege is in the privilege list
417 ****************************************************************************/
418 BOOL check_priv_in_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
422 /* if the list is empty, obviously we can't have it */
423 if (check_empty_privilege(priv_set))
426 for (i=0; i<priv_set->count; i++) {
429 cur_set=&priv_set->set[i];
430 /* check only the low and high part. Checking the attr field has no meaning */
431 if( (cur_set->luid.low==set.luid.low) && (cur_set->luid.high==set.luid.high) )
438 /****************************************************************************
439 remove a privilege to a privilege array
440 ****************************************************************************/
441 BOOL remove_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
447 /* check if the privilege is in the list */
448 if (!check_priv_in_privilege(priv_set, set))
451 /* special case if it's the only privilege in the list */
452 if (priv_set->count==1) {
453 free_privilege(priv_set);
454 init_privilege(priv_set);
460 * the privilege is there, create a new list,
461 * and copy the other privileges
464 old_set=priv_set->set;
466 new_set=(LUID_ATTR *)malloc((priv_set->count-1)*(sizeof(LUID_ATTR)));
468 DEBUG(0,("remove_privilege: could not malloc memory for new privilege list\n"));
472 for (i=0, j=0; i<priv_set->count; i++) {
473 if ((old_set[i].luid.low==set.luid.low) &&
474 (old_set[i].luid.high==set.luid.high)) {
478 new_set[j].luid.low=old_set[i].luid.low;
479 new_set[j].luid.high=old_set[i].luid.high;
480 new_set[j].attr=old_set[i].attr;
485 if (j!=priv_set->count-1) {
486 DEBUG(0,("remove_privilege: mismatch ! difference is not -1\n"));
487 DEBUGADD(0,("old count:%d, new count:%d\n", priv_set->count, j));
492 /* ok everything is fine */
495 priv_set->set=new_set;
502 /****************************************************************************
503 return the sid and the type of the unix group
504 ****************************************************************************/
505 BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
514 if(!init_group_mapping()) {
515 DEBUG(0,("failed to initialize group mapping"));
519 /* the key is the SID, retrieving is direct */
521 sid_to_string(string_sid, &sid);
522 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
525 kbuf.dsize = strlen(key)+1;
527 dbuf = tdb_fetch(tdb, kbuf);
528 if (!dbuf.dptr) return False;
530 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
531 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->systemaccount);
535 ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
537 DEBUG(10,("get_group_map_from_sid: %d privileges\n", map->priv_set.count));
541 set->set=(LUID_ATTR *)smb_xmalloc(set->count*sizeof(LUID_ATTR));
544 for (i=0; i<set->count; i++)
545 ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd",
546 &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
548 SAFE_FREE(dbuf.dptr);
549 if (ret != dbuf.dsize) {
550 DEBUG(0,("get_group_map_from_sid: group mapping TDB corrupted ?\n"));
555 /* we don't want the privileges */
556 if (with_priv==MAPPING_WITHOUT_PRIV)
559 sid_copy(&map->sid, &sid);
565 /****************************************************************************
566 return the sid and the type of the unix group
567 ****************************************************************************/
568 BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv)
570 TDB_DATA kbuf, dbuf, newkey;
576 if(!init_group_mapping()) {
577 DEBUG(0,("failed to initialize group mapping"));
581 /* we need to enumerate the TDB to find the GID */
583 for (kbuf = tdb_firstkey(tdb);
585 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
587 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue;
589 dbuf = tdb_fetch(tdb, kbuf);
590 if (!dbuf.dptr) continue;
592 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
594 string_to_sid(&map->sid, string_sid);
596 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
597 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->systemaccount);
600 ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
603 set->set=(LUID_ATTR *)smb_xmalloc(set->count*sizeof(LUID_ATTR));
606 for (i=0; i<set->count; i++)
607 ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd",
608 &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
610 SAFE_FREE(dbuf.dptr);
611 if (ret != dbuf.dsize){
618 free_privilege(&map->priv_set);
628 /****************************************************************************
629 return the sid and the type of the unix group
630 ****************************************************************************/
631 BOOL get_group_map_from_ntname(char *name, GROUP_MAP *map, BOOL with_priv)
633 TDB_DATA kbuf, dbuf, newkey;
639 if(!init_group_mapping()) {
640 DEBUG(0,("failed to initialize group mapping"));
644 /* we need to enumerate the TDB to find the name */
646 for (kbuf = tdb_firstkey(tdb);
648 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
650 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0) continue;
652 dbuf = tdb_fetch(tdb, kbuf);
653 if (!dbuf.dptr) continue;
655 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
657 string_to_sid(&map->sid, string_sid);
659 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
660 &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->systemaccount);
663 ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
665 set->set=(LUID_ATTR *)malloc(set->count*sizeof(LUID_ATTR));
666 if (set->set==NULL) {
667 DEBUG(0,("get_group_map_from_ntname: could not allocate memory for privileges\n"));
671 for (i=0; i<set->count; i++)
672 ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd",
673 &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
675 SAFE_FREE(dbuf.dptr);
676 if (ret != dbuf.dsize) {
681 if (StrCaseCmp(name, map->nt_name)==0) {
683 free_privilege(&map->priv_set);
693 /****************************************************************************
694 remove a group mapping entry
695 ****************************************************************************/
696 BOOL group_map_remove(DOM_SID sid)
702 if(!init_group_mapping()) {
703 DEBUG(0,("failed to initialize group mapping"));
707 /* the key is the SID, retrieving is direct */
709 sid_to_string(string_sid, &sid);
710 slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
713 kbuf.dsize = strlen(key)+1;
715 dbuf = tdb_fetch(tdb, kbuf);
716 if (!dbuf.dptr) return False;
718 SAFE_FREE(dbuf.dptr);
720 if(tdb_delete(tdb, kbuf) != TDB_SUCCESS)
727 /****************************************************************************
728 enumerate the group mapping
729 ****************************************************************************/
730 BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
731 int *num_entries, BOOL unix_only, BOOL with_priv)
733 TDB_DATA kbuf, dbuf, newkey;
743 if(!init_group_mapping()) {
744 DEBUG(0,("failed to initialize group mapping"));
751 for (kbuf = tdb_firstkey(tdb);
753 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
755 if (strncmp(kbuf.dptr, GROUP_PREFIX, strlen(GROUP_PREFIX)) != 0)
758 dbuf = tdb_fetch(tdb, kbuf);
762 fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
764 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
765 &map.gid, &map.sid_name_use, &map.nt_name, &map.comment, &map.systemaccount);
770 ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
773 set->set=(LUID_ATTR *)malloc(set->count*sizeof(LUID_ATTR));
774 if (set->set==NULL) {
775 DEBUG(0,("enum_group_mapping: could not allocate memory for privileges\n"));
780 for (i=0; i<set->count; i++)
781 ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd",
782 &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
784 SAFE_FREE(dbuf.dptr);
785 if (ret != dbuf.dsize) {
786 DEBUG(11,("enum_group_mapping: error in memory size\n"));
791 /* list only the type or everything if UNKNOWN */
792 if (sid_name_use!=SID_NAME_UNKNOWN && sid_name_use!=map.sid_name_use) {
793 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
798 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
799 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
804 string_to_sid(&map.sid, string_sid);
806 decode_sid_name_use(group_type, map.sid_name_use);
807 DEBUG(11,("enum_group_mapping: returning group %s of type %s\n", map.nt_name ,group_type));
809 mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
811 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
819 mapt[entries].gid = map.gid;
820 sid_copy( &mapt[entries].sid, &map.sid);
821 mapt[entries].sid_name_use = map.sid_name_use;
822 fstrcpy(mapt[entries].nt_name, map.nt_name);
823 fstrcpy(mapt[entries].comment, map.comment);
824 mapt[entries].systemaccount=map.systemaccount;
825 mapt[entries].priv_set.count=set->count;
826 mapt[entries].priv_set.control=set->control;
827 mapt[entries].priv_set.set=set->set;
829 free_privilege(&(mapt[entries].priv_set));
834 *num_entries=entries;
839 /****************************************************************************
840 convert a privilege string to a privilege array
841 ****************************************************************************/
842 void convert_priv_from_text(PRIVILEGE_SET *se_priv, char *privilege)
849 /* By default no privilege */
850 init_privilege(se_priv);
855 while(next_token(&p, tok, " ", sizeof(tok)) ) {
856 for (i=0; i<=PRIV_ALL_INDEX; i++) {
857 if (StrCaseCmp(privs[i].priv, tok)==0) {
860 set.luid.low=privs[i].se_priv;
861 add_privilege(se_priv, set);
867 /****************************************************************************
868 convert a privilege array to a privilege string
869 ****************************************************************************/
870 void convert_priv_to_text(PRIVILEGE_SET *se_priv, char *privilege)
877 ZERO_STRUCTP(privilege);
879 if (check_empty_privilege(se_priv)) {
880 fstrcat(privilege, "No privilege");
884 for(i=0; i<se_priv->count; i++) {
886 while (privs[j].se_priv!=se_priv->set[i].luid.low && j<=PRIV_ALL_INDEX) {
890 fstrcat(privilege, privs[j].priv);
891 fstrcat(privilege, " ");
898 * High level functions
899 * better to use them than the lower ones.
901 * we are checking if the group is in the mapping file
902 * and if the group is an existing unix group
906 /* get a domain group from it's SID */
908 BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
912 if(!init_group_mapping()) {
913 DEBUG(0,("failed to initialize group mapping"));
917 DEBUG(10, ("get_domain_group_from_sid\n"));
919 /* if the group is NOT in the database, it CAN NOT be a domain group */
920 if(!get_group_map_from_sid(sid, map, with_priv))
923 DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n"));
925 /* if it's not a domain group, continue */
926 if (map->sid_name_use!=SID_NAME_DOM_GRP) {
928 free_privilege(&map->priv_set);
932 DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n"));
936 free_privilege(&map->priv_set);
940 DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%d\n",map->gid));
942 if ( (grp=getgrgid(map->gid)) == NULL) {
943 DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n"));
945 free_privilege(&map->priv_set);
949 DEBUG(10, ("get_domain_group_from_sid: gid exists in UNIX security\n"));
955 /* get a local (alias) group from it's SID */
957 BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
961 if(!init_group_mapping()) {
962 DEBUG(0,("failed to initialize group mapping"));
966 /* The group is in the mapping table */
967 if(get_group_map_from_sid(sid, map, with_priv)) {
968 if (map->sid_name_use!=SID_NAME_ALIAS) {
970 free_privilege(&map->priv_set);
976 free_privilege(&map->priv_set);
980 if ( (grp=getgrgid(map->gid)) == NULL) {
982 free_privilege(&map->priv_set);
986 /* the group isn't in the mapping table.
987 * make one based on the unix information */
990 sid_peek_rid(&sid, &alias_rid);
991 map->gid=pdb_group_rid_to_gid(alias_rid);
993 if ((grp=getgrgid(map->gid)) == NULL)
996 map->sid_name_use=SID_NAME_ALIAS;
997 map->systemaccount=PR_ACCESS_FROM_NETWORK;
999 fstrcpy(map->nt_name, grp->gr_name);
1000 fstrcpy(map->comment, "Local Unix Group");
1002 init_privilege(&map->priv_set);
1004 sid_copy(&map->sid, &sid);
1010 /* get a builtin group from it's SID */
1012 BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
1016 if(!init_group_mapping()) {
1017 DEBUG(0,("failed to initialize group mapping"));
1021 if(!get_group_map_from_sid(sid, map, with_priv))
1024 if (map->sid_name_use!=SID_NAME_WKN_GRP) {
1026 free_privilege(&map->priv_set);
1032 free_privilege(&map->priv_set);
1036 if ( (grp=getgrgid(map->gid)) == NULL) {
1038 free_privilege(&map->priv_set);
1047 /****************************************************************************
1048 Returns a GROUP_MAP struct based on the gid.
1049 ****************************************************************************/
1050 BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv)
1054 if(!init_group_mapping()) {
1055 DEBUG(0,("failed to initialize group mapping"));
1059 if ( (grp=getgrgid(gid)) == NULL)
1063 * make a group map from scratch if doesn't exist.
1065 if (!get_group_map_from_gid(gid, map, with_priv)) {
1067 map->sid_name_use=SID_NAME_ALIAS;
1068 map->systemaccount=PR_ACCESS_FROM_NETWORK;
1069 init_privilege(&map->priv_set);
1071 /* interim solution until we have a last RID allocated */
1073 sid_copy(&map->sid, &global_sam_sid);
1074 sid_append_rid(&map->sid, pdb_gid_to_group_rid(gid));
1076 fstrcpy(map->nt_name, grp->gr_name);
1077 fstrcpy(map->comment, "Local Unix Group");
1086 /****************************************************************************
1087 Get the member users of a group and
1088 all the users who have that group as primary.
1090 give back an array of uid
1091 return the grand number of users
1094 TODO: sort the list and remove duplicate. JFM.
1096 ****************************************************************************/
1098 BOOL get_uid_list_of_group(gid_t gid, uid_t **uid, int *num_uids)
1106 if(!init_group_mapping()) {
1107 DEBUG(0,("failed to initialize group mapping"));
1114 if ( (grp=getgrgid(gid)) == NULL)
1117 gr = grp->gr_mem[0];
1118 DEBUG(10, ("getting members\n"));
1120 while (gr && (*gr != (char)'\0')) {
1121 u = Realloc((*uid), sizeof(uid_t)*(*num_uids+1));
1123 DEBUG(0,("get_uid_list_of_group: unable to enlarge uid list!\n"));
1128 if( (pwd=getpwnam_alloc(gr)) !=NULL) {
1129 (*uid)[*num_uids]=pwd->pw_uid;
1133 gr = grp->gr_mem[++i];
1135 DEBUG(10, ("got [%d] members\n", *num_uids));
1138 while ((pwd=getpwent()) != NULL) {
1139 if (pwd->pw_gid==gid) {
1140 u = Realloc((*uid), sizeof(uid_t)*(*num_uids+1));
1142 DEBUG(0,("get_uid_list_of_group: unable to enlarge uid list!\n"));
1146 (*uid)[*num_uids]=pwd->pw_uid;
1152 DEBUG(10, ("got primary groups, members: [%d]\n", *num_uids));
1157 /****************************************************************************
1158 Create a UNIX group on demand.
1159 ****************************************************************************/
1161 int smb_create_group(char *unix_group)
1166 pstrcpy(add_script, lp_addgroup_script());
1167 if (! *add_script) return -1;
1168 pstring_sub(add_script, "%g", unix_group);
1169 ret = smbrun(add_script,NULL);
1170 DEBUG(3,("smb_create_group: Running the command `%s' gave %d\n",add_script,ret));
1174 /****************************************************************************
1175 Delete a UNIX group on demand.
1176 ****************************************************************************/
1178 int smb_delete_group(char *unix_group)
1183 pstrcpy(del_script, lp_delgroup_script());
1184 if (! *del_script) return -1;
1185 pstring_sub(del_script, "%g", unix_group);
1186 ret = smbrun(del_script,NULL);
1187 DEBUG(3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
1191 /****************************************************************************
1192 Create a UNIX group on demand.
1193 ****************************************************************************/
1195 int smb_add_user_group(char *unix_group, char *unix_user)
1200 pstrcpy(add_script, lp_addusertogroup_script());
1201 if (! *add_script) return -1;
1202 pstring_sub(add_script, "%g", unix_group);
1203 pstring_sub(add_script, "%u", unix_user);
1204 ret = smbrun(add_script,NULL);
1205 DEBUG(3,("smb_add_user_group: Running the command `%s' gave %d\n",add_script,ret));
1209 /****************************************************************************
1210 Delete a UNIX group on demand.
1211 ****************************************************************************/
1213 int smb_delete_user_group(const char *unix_group, const char *unix_user)
1218 pstrcpy(del_script, lp_deluserfromgroup_script());
1219 if (! *del_script) return -1;
1220 pstring_sub(del_script, "%g", unix_group);
1221 pstring_sub(del_script, "%u", unix_user);
1222 ret = smbrun(del_script,NULL);
1223 DEBUG(3,("smb_delete_user_group: Running the command `%s' gave %d\n",del_script,ret));