2
Unix SMB/CIFS implementation.
4
Winbind account management functions
6
Copyright (C) by Gerald (Jerry) Carter 2003
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
#define DBGC_CLASS DBGC_WINBIND
29
#define WBKEY_PASSWD "WBA_PASSWD"
30
#define WBKEY_GROUP "WBA_GROUP"
32
#define NUM_PW_FIELDS 7
33
#define NUM_GRP_FIELDS 4
37
static TDB_CONTEXT *account_tdb;
39
extern userdom_struct current_user_info;
41
struct _check_primary_grp {
46
/**********************************************************************
47
**********************************************************************/
49
static void free_winbindd_gr( WINBINDD_GR *grp )
56
for ( i=0; i<grp->num_gr_mem; i++ )
57
SAFE_FREE( grp->gr_mem[i] );
59
SAFE_FREE( grp->gr_mem );
64
/*****************************************************************************
65
Initialise auto-account database.
66
*****************************************************************************/
68
static BOOL winbindd_accountdb_init(void)
70
/* see if we've already opened the tdb */
75
/* winbindd_idmap.tdb should always be opened by the idmap_init()
78
if ( !(account_tdb = idmap_tdb_handle()) ) {
79
DEBUG(0, ("winbindd_accountdb_init: Unable to retreive handle for database\n"));
88
/**********************************************************************
89
Convert a string in /etc/passwd format to a struct passwd* entry
90
**********************************************************************/
92
static WINBINDD_PW* string2passwd( char *string )
94
static WINBINDD_PW pw;
96
char *fields[NUM_PW_FIELDS];
104
DEBUG(10,("string2passwd: converting \"%s\"\n", string));
106
ZERO_STRUCT( fields );
108
for ( i=0, str=string; i<NUM_PW_FIELDS-1; i++ ) {
109
if ( !(p = strchr( str, ':' )) ) {
110
DEBUG(0,("string2passwd: parsing failure\n"));
123
fstrcpy( pw.pw_name, fields[0] );
124
fstrcpy( pw.pw_passwd, fields[1] );
125
pw.pw_uid = atoi( fields[2] );
126
pw.pw_gid = atoi( fields[3] );
127
fstrcpy( pw.pw_gecos, fields[4] );
128
fstrcpy( pw.pw_dir, fields[5] );
129
fstrcpy( pw.pw_shell, fields[6] );
132
/* last minute sanity checks */
134
if ( pw.pw_uid==0 || pw.pw_gid==0 ) {
135
DEBUG(0,("string2passwd: Failure! uid==%lu, gid==%lu\n",
136
(unsigned long)pw.pw_uid, (unsigned long)pw.pw_gid));
140
DEBUG(10,("string2passwd: Success\n"));
145
/**********************************************************************
146
Convert a struct passwd* to a string formatted for /etc/passwd
147
**********************************************************************/
149
static char* passwd2string( const WINBINDD_PW *pw )
151
static pstring string;
154
if ( !pw || !pw->pw_name )
157
DEBUG(10,("passwd2string: converting passwd struct for %s\n",
160
ret = pstr_sprintf( string, "%s:%s:%lu:%lu:%s:%s:%s",
162
pw->pw_passwd ? pw->pw_passwd : "x",
163
(unsigned long)pw->pw_uid,
164
(unsigned long)pw->pw_gid,
170
DEBUG(0,("passwd2string: pstr_sprintf() failed!\n"));
177
/**********************************************************************
178
Convert a string in /etc/group format to a struct group* entry
179
**********************************************************************/
181
static WINBINDD_GR* string2group( char *string )
183
static WINBINDD_GR grp;
185
char *fields[NUM_GRP_FIELDS];
187
char **gr_members = NULL;
188
int num_gr_members = 0;
193
ZERO_STRUCTP( &grp );
195
DEBUG(10,("string2group: converting \"%s\"\n", string));
197
ZERO_STRUCT( fields );
199
for ( i=0, str=string; i<NUM_GRP_FIELDS-1; i++ ) {
200
if ( !(p = strchr( str, ':' )) ) {
201
DEBUG(0,("string2group: parsing failure\n"));
213
/* we already know we have a non-empty string */
215
num_gr_members = count_chars(str, ',') + 1;
217
/* if there was at least one comma, then there
219
if ( num_gr_members ) {
222
gr_members = (char**)smb_xmalloc(sizeof(char*)*(num_gr_members+1));
225
while ( next_token(&str, buffer, ",", sizeof(buffer)) && i<num_gr_members ) {
226
gr_members[i++] = smb_xstrdup(buffer);
229
gr_members[i] = NULL;
236
fstrcpy( grp.gr_name, fields[0] );
237
fstrcpy( grp.gr_passwd, fields[1] );
238
grp.gr_gid = atoi( fields[2] );
240
grp.num_gr_mem = num_gr_members;
241
grp.gr_mem = gr_members;
243
/* last minute sanity checks */
245
if ( grp.gr_gid == 0 ) {
246
DEBUG(0,("string2group: Failure! gid==%lu\n", (unsigned long)grp.gr_gid));
247
SAFE_FREE( gr_members );
251
DEBUG(10,("string2group: Success\n"));
256
/**********************************************************************
257
Convert a struct group* to a string formatted for /etc/group
258
**********************************************************************/
260
static char* group2string( const WINBINDD_GR *grp )
262
static pstring string;
264
char *member, *gr_mem_str;
268
if ( !grp || !grp->gr_name )
271
DEBUG(10,("group2string: converting passwd struct for %s\n",
274
if ( grp->num_gr_mem ) {
277
member = grp->gr_mem[0];
282
size += strlen(member) + 1;
284
member = grp->gr_mem[num_members];
287
gr_mem_str = smb_xmalloc(size);
289
for ( i=0; i<num_members; i++ ) {
290
snprintf( &gr_mem_str[idx], size-idx, "%s,", grp->gr_mem[i] );
291
idx += strlen(grp->gr_mem[i]) + 1;
293
/* add trailing NULL (also removes trailing ',' */
294
gr_mem_str[size-1] = '\0';
298
gr_mem_str = smb_xmalloc(sizeof(fstring));
299
fstrcpy( gr_mem_str, "" );
302
ret = pstr_sprintf( string, "%s:%s:%lu:%s",
304
grp->gr_passwd ? grp->gr_passwd : "*",
305
(unsigned long)grp->gr_gid,
308
SAFE_FREE( gr_mem_str );
311
DEBUG(0,("group2string: pstr_sprintf() failed!\n"));
318
/**********************************************************************
319
**********************************************************************/
321
static char* acct_userkey_byname( const char *name )
325
fstr_sprintf( key, "%s/NAME/%s", WBKEY_PASSWD, name );
330
/**********************************************************************
331
**********************************************************************/
333
static char* acct_userkey_byuid( uid_t uid )
337
fstr_sprintf( key, "%s/UID/%lu", WBKEY_PASSWD, (unsigned long)uid );
342
/**********************************************************************
343
**********************************************************************/
345
static char* acct_groupkey_byname( const char *name )
349
fstr_sprintf( key, "%s/NAME/%s", WBKEY_GROUP, name );
354
/**********************************************************************
355
**********************************************************************/
357
static char* acct_groupkey_bygid( gid_t gid )
361
fstr_sprintf( key, "%s/GID/%lu", WBKEY_GROUP, (unsigned long)gid );
366
/**********************************************************************
367
**********************************************************************/
369
WINBINDD_PW* wb_getpwnam( const char * name )
373
static WINBINDD_PW *pw;
375
if ( !account_tdb && !winbindd_accountdb_init() ) {
376
DEBUG(0,("wb_getpwnam: Failed to open winbindd account db\n"));
381
keystr = acct_userkey_byname( name );
383
data = tdb_fetch_bystring( account_tdb, keystr );
388
pw = string2passwd( data.dptr );
389
SAFE_FREE( data.dptr );
392
DEBUG(5,("wb_getpwnam: %s user (%s)\n",
393
(pw ? "Found" : "Did not find"), name ));
398
/**********************************************************************
399
**********************************************************************/
401
WINBINDD_PW* wb_getpwuid( const uid_t uid )
405
static WINBINDD_PW *pw;
407
if ( !account_tdb && !winbindd_accountdb_init() ) {
408
DEBUG(0,("wb_getpwuid: Failed to open winbindd account db\n"));
412
data = tdb_fetch_bystring( account_tdb, acct_userkey_byuid(uid) );
414
DEBUG(4,("wb_getpwuid: failed to locate uid == %lu\n", (unsigned long)uid));
417
keystr = acct_userkey_byname( data.dptr );
419
SAFE_FREE( data.dptr );
421
data = tdb_fetch_bystring( account_tdb, keystr );
426
pw = string2passwd( data.dptr );
427
SAFE_FREE( data.dptr );
430
DEBUG(5,("wb_getpwuid: %s user (uid == %lu)\n",
431
(pw ? "Found" : "Did not find"), (unsigned long)uid ));
436
/**********************************************************************
437
**********************************************************************/
439
static BOOL wb_storepwnam( const WINBINDD_PW *pw )
441
char *namekey, *uidkey;
447
if ( !account_tdb && !winbindd_accountdb_init() ) {
448
DEBUG(0,("wb_storepwnam: Failed to open winbindd account db\n"));
452
namekey = acct_userkey_byname( pw->pw_name );
454
/* lock the main entry first */
456
if ( tdb_lock_bystring(account_tdb, namekey, 0) == -1 ) {
457
DEBUG(0,("wb_storepwnam: Failed to lock %s\n", namekey));
461
str = passwd2string( pw );
464
data.dsize = strlen(str) + 1;
466
if ( (tdb_store_bystring(account_tdb, namekey, data, TDB_REPLACE)) == -1 ) {
467
DEBUG(0,("wb_storepwnam: Failed to store \"%s\"\n", str));
472
/* store the uid index */
474
uidkey = acct_userkey_byuid(pw->pw_uid);
476
fstrcpy( username, pw->pw_name );
477
data.dptr = username;
478
data.dsize = strlen(username) + 1;
480
if ( (tdb_store_bystring(account_tdb, uidkey, data, TDB_REPLACE)) == -1 ) {
481
DEBUG(0,("wb_storepwnam: Failed to store uid key \"%s\"\n", str));
482
tdb_delete_bystring(account_tdb, namekey);
487
DEBUG(10,("wb_storepwnam: Success -> \"%s\"\n", str));
490
tdb_unlock_bystring( account_tdb, namekey );
495
/**********************************************************************
496
**********************************************************************/
498
WINBINDD_GR* wb_getgrnam( const char * name )
502
static WINBINDD_GR *grp;
504
if ( !account_tdb && !winbindd_accountdb_init() ) {
505
DEBUG(0,("wb_getgrnam: Failed to open winbindd account db\n"));
510
keystr = acct_groupkey_byname( name );
512
data = tdb_fetch_bystring( account_tdb, keystr );
517
grp = string2group( data.dptr );
518
SAFE_FREE( data.dptr );
521
DEBUG(5,("wb_getgrnam: %s group (%s)\n",
522
(grp ? "Found" : "Did not find"), name ));
527
/**********************************************************************
528
**********************************************************************/
530
WINBINDD_GR* wb_getgrgid( gid_t gid )
534
static WINBINDD_GR *grp;
536
if ( !account_tdb && !winbindd_accountdb_init() ) {
537
DEBUG(0,("wb_getgrgid: Failed to open winbindd account db\n"));
541
data = tdb_fetch_bystring( account_tdb, acct_groupkey_bygid(gid) );
543
DEBUG(4,("wb_getgrgid: failed to locate gid == %lu\n",
544
(unsigned long)gid));
547
keystr = acct_groupkey_byname( data.dptr );
549
SAFE_FREE( data.dptr );
551
data = tdb_fetch_bystring( account_tdb, keystr );
556
grp = string2group( data.dptr );
557
SAFE_FREE( data.dptr );
560
DEBUG(5,("wb_getgrgid: %s group (gid == %lu)\n",
561
(grp ? "Found" : "Did not find"), (unsigned long)gid ));
566
/**********************************************************************
567
**********************************************************************/
569
static BOOL wb_storegrnam( const WINBINDD_GR *grp )
571
char *namekey, *gidkey;
577
if ( !account_tdb && !winbindd_accountdb_init() ) {
578
DEBUG(0,("wb_storepwnam: Failed to open winbindd account db\n"));
582
namekey = acct_groupkey_byname( grp->gr_name );
584
/* lock the main entry first */
586
if ( tdb_lock_bystring(account_tdb, namekey, 0) == -1 ) {
587
DEBUG(0,("wb_storegrnam: Failed to lock %s\n", namekey));
591
str = group2string( grp );
594
data.dsize = strlen(str) + 1;
596
if ( (tdb_store_bystring(account_tdb, namekey, data, TDB_REPLACE)) == -1 ) {
597
DEBUG(0,("wb_storegrnam: Failed to store \"%s\"\n", str));
602
/* store the gid index */
604
gidkey = acct_groupkey_bygid(grp->gr_gid);
606
fstrcpy( groupname, grp->gr_name );
607
data.dptr = groupname;
608
data.dsize = strlen(groupname) + 1;
610
if ( (tdb_store_bystring(account_tdb, gidkey, data, TDB_REPLACE)) == -1 ) {
611
DEBUG(0,("wb_storegrnam: Failed to store gid key \"%s\"\n", str));
612
tdb_delete_bystring(account_tdb, namekey);
617
DEBUG(10,("wb_storegrnam: Success -> \"%s\"\n", str));
620
tdb_unlock_bystring( account_tdb, namekey );
625
/**********************************************************************
626
**********************************************************************/
628
static BOOL wb_addgrpmember( WINBINDD_GR *grp, const char *user )
636
for ( i=0; i<grp->num_gr_mem; i++ ) {
637
if ( StrCaseCmp( grp->gr_mem[i], user ) == 0 )
641
/* add one new slot and keep an extra for the terminating NULL */
642
members = Realloc( grp->gr_mem, (grp->num_gr_mem+2)*sizeof(char*) );
646
grp->gr_mem = members;
647
grp->gr_mem[grp->num_gr_mem++] = smb_xstrdup(user);
648
grp->gr_mem[grp->num_gr_mem] = NULL;
653
/**********************************************************************
654
**********************************************************************/
656
static BOOL wb_delgrpmember( WINBINDD_GR *grp, const char *user )
664
for ( i=0; i<grp->num_gr_mem; i++ ) {
665
if ( StrCaseCmp( grp->gr_mem[i], user ) == 0 ) {
674
/* still some remaining members */
676
if ( grp->num_gr_mem > 1 ) {
677
SAFE_FREE(grp->gr_mem[i]);
679
grp->gr_mem[i] = grp->gr_mem[grp->num_gr_mem];
680
grp->gr_mem[grp->num_gr_mem] = NULL;
682
else { /* last one */
683
free_winbindd_gr( grp );
691
/**********************************************************************
692
**********************************************************************/
694
static int cleangroups_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
699
char *name = (char*)state;
701
fstr_sprintf( key, "%s/NAME", WBKEY_GROUP );
704
/* if this is a group entry then, check the members */
706
if ( (strncmp(kbuf.dptr, key, len) == 0) && dbuf.dptr ) {
709
if ( !(grp = string2group( dbuf.dptr )) ) {
710
DEBUG(0,("cleangroups_traverse_fn: Failure to parse [%s]\n",
715
/* just try to delete the user and rely on wb_delgrpmember()
716
to tell you whether or not the group changed. This is more
717
effecient than testing group membership first since the
718
checks for deleting a user from a group is essentially the
719
same as checking if he/she is a member */
721
if ( wb_delgrpmember( grp, name ) ) {
722
DEBUG(10,("cleanupgroups_traverse_fn: Removed user (%s) from group (%s)\n",
723
name, grp->gr_name));
724
wb_storegrnam( grp );
727
free_winbindd_gr( grp );
733
/**********************************************************************
734
**********************************************************************/
736
static BOOL wb_delete_user( WINBINDD_PW *pw)
741
if ( !account_tdb && !winbindd_accountdb_init() ) {
742
DEBUG(0,("wb_delete_user: Failed to open winbindd account db\n"));
746
namekey = acct_userkey_byname( pw->pw_name );
748
/* lock the main entry first */
750
if ( tdb_lock_bystring(account_tdb, namekey, 0) == -1 ) {
751
DEBUG(0,("wb_delete_user: Failed to lock %s\n", namekey));
755
/* remove user from all groups */
757
tdb_traverse(account_tdb, cleangroups_traverse_fn, (void *)pw->pw_name);
759
/* remove the user */
760
uidkey = acct_userkey_byuid( pw->pw_uid );
762
tdb_delete_bystring( account_tdb, namekey );
763
tdb_delete_bystring( account_tdb, uidkey );
765
tdb_unlock_bystring( account_tdb, namekey );
770
/**********************************************************************
771
**********************************************************************/
773
static int isprimarygroup_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf,
774
TDB_DATA dbuf, void *params)
778
struct _check_primary_grp *check = (struct _check_primary_grp*)params;
780
fstr_sprintf( key, "%s/NAME", WBKEY_PASSWD );
783
/* if this is a group entry then, check the members */
785
if ( (strncmp(kbuf.dptr, key, len) == 0) && dbuf.dptr ) {
788
if ( !(pw = string2passwd( dbuf.dptr )) ) {
789
DEBUG(0,("isprimarygroup_traverse_fn: Failure to parse [%s]\n",
794
if ( check->gid == pw->pw_gid ) {
804
/**********************************************************************
805
**********************************************************************/
807
static BOOL wb_delete_group( WINBINDD_GR *grp )
809
struct _check_primary_grp check;
813
if ( !account_tdb && !winbindd_accountdb_init() ) {
814
DEBUG(0,("wb_delete_group: Failed to open winbindd account db\n"));
818
/* lock the main entry first */
820
namekey = acct_groupkey_byname( grp->gr_name );
821
if ( tdb_lock_bystring(account_tdb, namekey, 0) == -1 ) {
822
DEBUG(0,("wb_delete_group: Failed to lock %s\n", namekey));
826
/* is this group the primary group for any user? If
830
tdb_traverse(account_tdb, isprimarygroup_traverse_fn, (void *)&check);
833
DEBUG(4,("wb_delete_group: Cannot delete group (%s) since it "
834
"is the primary group for some users\n", grp->gr_name));
838
/* We're clear. Delete the group */
840
DEBUG(5,("wb_delete_group: Removing group (%s)\n", grp->gr_name));
842
gidkey = acct_groupkey_bygid( grp->gr_gid );
844
tdb_delete_bystring( account_tdb, namekey );
845
tdb_delete_bystring( account_tdb, gidkey );
847
tdb_unlock_bystring( account_tdb, namekey );
852
/**********************************************************************
853
Create a new "UNIX" user for the system given a username
854
**********************************************************************/
856
enum winbindd_result winbindd_create_user(struct winbindd_cli_state *state)
860
WINBINDD_PW pw, *pw_check;
862
struct group *unix_grp;
864
uint32 flags = state->request.flags;
867
if ( !state->privileged ) {
868
DEBUG(2, ("winbindd_create_user: non-privileged access denied!\n"));
869
return WINBINDD_ERROR;
872
/* Ensure null termination */
873
state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
874
state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
876
user = state->request.data.acct_mgt.username;
877
group = state->request.data.acct_mgt.groupname;
879
DEBUG(3, ("[%5lu]: create_user: user=>(%s), group=>(%s)\n",
880
(unsigned long)state->pid, user, group));
882
if ( (pw_check=wb_getpwnam(user)) != NULL ) {
883
DEBUG(0,("winbindd_create_user: Refusing to create user that already exists (%s)\n",
885
return WINBINDD_ERROR;
890
group = lp_template_primary_group();
892
/* validate the primary group
893
1) lookup in local tdb first
894
2) call getgrnam() as a last resort */
896
if ( (wb_grp=wb_getgrnam(group)) != NULL ) {
897
primary_gid = wb_grp->gr_gid;
898
free_winbindd_gr( wb_grp );
900
else if ( (unix_grp=sys_getgrnam(group)) != NULL ) {
901
primary_gid = unix_grp->gr_gid;
904
DEBUG(2,("winbindd_create_user: Cannot validate gid for group (%s)\n", group));
905
return WINBINDD_ERROR;
910
if ( !NT_STATUS_IS_OK(idmap_allocate_id( &id, ID_USERID)) ) {
911
DEBUG(0,("winbindd_create_user: idmap_allocate_id() failed!\n"));
912
return WINBINDD_ERROR;
915
/* The substitution of %U and %D in the 'template homedir' is done
916
by lp_string() calling standard_sub_basic(). */
918
fstrcpy( current_user_info.smb_name, user );
919
sub_set_smb_name( user );
920
fstrcpy( current_user_info.domain, get_global_sam_name() );
922
/* fill in the passwd struct */
924
fstrcpy( pw.pw_name, user );
925
fstrcpy( pw.pw_passwd, "x" );
926
fstrcpy( pw.pw_gecos, user);
927
fstrcpy( pw.pw_dir, lp_template_homedir() );
928
fstrcpy( pw.pw_shell, lp_template_shell() );
931
pw.pw_gid = primary_gid;
933
/* store the new entry */
935
if ( !wb_storepwnam(&pw) )
936
return WINBINDD_ERROR;
938
/* do we need a new RID? */
940
if ( flags & WBFLAG_ALLOCATE_RID ) {
941
if ( !NT_STATUS_IS_OK(idmap_allocate_rid(&rid, USER_RID_TYPE)) ) {
942
DEBUG(0,("winbindd_create_user: RID allocation failure! Cannot create user (%s)\n",
944
wb_delete_user( &pw );
946
return WINBINDD_ERROR;
949
state->response.data.rid = rid;
955
/**********************************************************************
956
Create a new "UNIX" group for the system given a username
957
**********************************************************************/
959
enum winbindd_result winbindd_create_group(struct winbindd_cli_state *state)
963
WINBINDD_GR grp, *grp_check;
964
uint32 flags = state->request.flags;
967
if ( !state->privileged ) {
968
DEBUG(2, ("winbindd_create_group: non-privileged access denied!\n"));
969
return WINBINDD_ERROR;
972
/* Ensure null termination */
973
state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
974
group = state->request.data.acct_mgt.groupname;
976
DEBUG(3, ("[%5lu]: create_group: (%s)\n", (unsigned long)state->pid, group));
978
if ( (grp_check=wb_getgrnam(group)) != NULL ) {
979
DEBUG(0,("winbindd_create_group: Refusing to create group that already exists (%s)\n",
981
return WINBINDD_ERROR;
986
if ( !NT_STATUS_IS_OK(idmap_allocate_id( &id, ID_GROUPID)) ) {
987
DEBUG(0,("winbindd_create_group: idmap_allocate_id() failed!\n"));
988
return WINBINDD_ERROR;
991
/* fill in the group struct */
993
fstrcpy( grp.gr_name, group );
994
fstrcpy( grp.gr_passwd, "*" );
997
grp.gr_mem = NULL; /* start with no members */
1000
if ( !wb_storegrnam(&grp) )
1001
return WINBINDD_ERROR;
1003
/* do we need a new RID? */
1005
if ( flags & WBFLAG_ALLOCATE_RID ) {
1006
if ( !NT_STATUS_IS_OK(idmap_allocate_rid(&rid, GROUP_RID_TYPE)) ) {
1007
DEBUG(0,("winbindd_create_group: RID allocation failure! Cannot create group (%s)\n",
1009
wb_delete_group( &grp );
1011
return WINBINDD_ERROR;
1014
state->response.data.rid = rid;
1020
/**********************************************************************
1021
Add a user to the membership for a group.
1022
**********************************************************************/
1024
enum winbindd_result winbindd_add_user_to_group(struct winbindd_cli_state *state)
1031
if ( !state->privileged ) {
1032
DEBUG(2, ("winbindd_add_user_to_group: non-privileged access denied!\n"));
1033
return WINBINDD_ERROR;
1036
/* Ensure null termination */
1037
state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
1038
state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
1039
group = state->request.data.acct_mgt.groupname;
1040
user = state->request.data.acct_mgt.username;
1042
DEBUG(3, ("[%5lu]: add_user_to_group: add %s to %s\n", (unsigned long)state->pid,
1045
/* make sure it is a valid user */
1047
if ( !(pw = wb_getpwnam( user )) ) {
1048
DEBUG(4,("winbindd_add_user_to_group: Cannot add a non-existent user\n"));
1049
return WINBINDD_ERROR;
1052
/* make sure it is a valid group */
1054
if ( !(grp = wb_getgrnam( group )) ) {
1055
DEBUG(4,("winbindd_add_user_to_group: Cannot add a user to a non-extistent group\n"));
1056
return WINBINDD_ERROR;
1059
if ( !wb_addgrpmember( grp, user ) )
1060
return WINBINDD_ERROR;
1062
ret = wb_storegrnam(grp);
1064
free_winbindd_gr( grp );
1066
return ( ret ? WINBINDD_OK : WINBINDD_ERROR );
1069
/**********************************************************************
1070
Remove a user from the membership of a group
1071
**********************************************************************/
1073
enum winbindd_result winbindd_remove_user_from_group(struct winbindd_cli_state *state)
1079
if ( !state->privileged ) {
1080
DEBUG(2, ("winbindd_remove_user_from_group: non-privileged access denied!\n"));
1081
return WINBINDD_ERROR;
1084
/* Ensure null termination */
1085
state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
1086
state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
1087
group = state->request.data.acct_mgt.groupname;
1088
user = state->request.data.acct_mgt.username;
1090
DEBUG(3, ("[%5lu]: remove_user_from_group: delete %s from %s\n", (unsigned long)state->pid,
1093
/* don't worry about checking the username since we're removing it anyways */
1095
/* make sure it is a valid group */
1097
if ( !(grp = wb_getgrnam( group )) ) {
1098
DEBUG(4,("winbindd_remove_user_from_group: Cannot remove a user from a non-extistent group\n"));
1099
return WINBINDD_ERROR;
1102
if ( !wb_delgrpmember( grp, user ) )
1103
return WINBINDD_ERROR;
1105
ret = wb_storegrnam(grp);
1107
free_winbindd_gr( grp );
1109
return ( ret ? WINBINDD_OK : WINBINDD_ERROR );
1112
/**********************************************************************
1113
Set the primary group membership of a user
1114
**********************************************************************/
1116
enum winbindd_result winbindd_set_user_primary_group(struct winbindd_cli_state *state)
1122
if ( !state->privileged ) {
1123
DEBUG(2, ("winbindd_set_user_primary_group: non-privileged access denied!\n"));
1124
return WINBINDD_ERROR;
1127
/* Ensure null termination */
1128
state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
1129
state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
1130
group = state->request.data.acct_mgt.groupname;
1131
user = state->request.data.acct_mgt.username;
1133
DEBUG(3, ("[%5lu]: set_user_primary_group: group %s for user %s\n",
1134
(unsigned long)state->pid, group, user));
1136
/* make sure it is a valid user */
1138
if ( !(pw = wb_getpwnam( user )) ) {
1139
DEBUG(4,("winbindd_add_user_to_group: Cannot add a non-existent user\n"));
1140
return WINBINDD_ERROR;
1143
/* make sure it is a valid group */
1145
if ( !(grp = wb_getgrnam( group )) ) {
1146
DEBUG(4,("winbindd_add_user_to_group: Cannot add a user to a non-extistent group\n"));
1147
return WINBINDD_ERROR;
1150
pw->pw_gid = grp->gr_gid;
1152
free_winbindd_gr( grp );
1154
return ( wb_storepwnam(pw) ? WINBINDD_OK : WINBINDD_ERROR );
1157
/**********************************************************************
1158
Delete a user from the winbindd account tdb.
1159
**********************************************************************/
1161
enum winbindd_result winbindd_delete_user(struct winbindd_cli_state *state)
1166
if ( !state->privileged ) {
1167
DEBUG(2, ("winbindd_delete_user: non-privileged access denied!\n"));
1168
return WINBINDD_ERROR;
1171
/* Ensure null termination */
1172
state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
1173
user = state->request.data.acct_mgt.username;
1175
DEBUG(3, ("[%5lu]: delete_user: %s\n", (unsigned long)state->pid, user));
1177
/* make sure it is a valid user */
1179
if ( !(pw = wb_getpwnam( user )) ) {
1180
DEBUG(4,("winbindd_delete_user: Cannot delete a non-existent user\n"));
1181
return WINBINDD_ERROR;
1184
return ( wb_delete_user(pw) ? WINBINDD_OK : WINBINDD_ERROR );
1187
/**********************************************************************
1188
Delete a group from winbindd's account tdb.
1189
**********************************************************************/
1191
enum winbindd_result winbindd_delete_group(struct winbindd_cli_state *state)
1197
if ( !state->privileged ) {
1198
DEBUG(2, ("winbindd_delete_group: non-privileged access denied!\n"));
1199
return WINBINDD_ERROR;
1202
/* Ensure null termination */
1203
state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
1204
group = state->request.data.acct_mgt.groupname;
1206
DEBUG(3, ("[%5lu]: delete_group: %s\n", (unsigned long)state->pid, group));
1208
/* make sure it is a valid group */
1210
if ( !(grp = wb_getgrnam( group )) ) {
1211
DEBUG(4,("winbindd_delete_group: Cannot delete a non-existent group\n"));
1212
return WINBINDD_ERROR;
1215
ret = wb_delete_group(grp);
1217
free_winbindd_gr( grp );
1219
return ( ret ? WINBINDD_OK : WINBINDD_ERROR );