| Provision-Unix documentation | Contained in the Provision-Unix distribution. |
Provision::Unix::User::Darwin - Provision Accounts on Darwin systems
Handles provisioning operations (create, modify, destroy) for system users on UNIX based operating systems.
use Provision::Unix::User::Darwin;
my $prov_user = Provision::Unix::User::Darwin->new();
...
Creates and returns a new Provision::Unix::User::Darwin object.
Matt Simerson, <matt at tnpi.net>
Please report any bugs or feature requests to bug-unix-provision-user at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Provision-Unix. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
You can find documentation for this module with the perldoc command.
perldoc Provision::Unix::User::Darwin
You can also look for information at:
Copyright 2008 Matt Simerson
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| Provision-Unix documentation | Contained in the Provision-Unix distribution. |
package Provision::Unix::User::Darwin; use warnings; use strict; our $VERSION = '0.16'; use English qw( -no_match_vars ); use Carp; use Params::Validate qw( :all ); use lib 'lib'; my ( $util, $prov, $p_user ); sub new { my $class = shift; my %p = validate( @_, { 'prov' => { type => OBJECT }, 'user' => { type => OBJECT }, } ); my $self = { prov => $p{prov}, user => $p{user}, }; bless( $self, $class ); $p_user = $p{user}; $prov = $p{prov}; $util = $prov->get_util; return $self; } sub create { my $self = shift; my %p = validate( @_, { 'username' => { type => SCALAR }, 'uid' => { type => SCALAR }, 'gid' => { type => SCALAR }, 'password' => { type => SCALAR | UNDEF, optional => 1 }, 'shell' => { type => SCALAR | UNDEF, optional => 1 }, 'homedir' => { type => SCALAR | UNDEF, optional => 1 }, 'gecos' => { type => SCALAR | UNDEF, optional => 1 }, 'domain' => { type => SCALAR | UNDEF, optional => 1 }, 'expire' => { type => SCALAR | UNDEF, optional => 1 }, 'quota' => { type => SCALAR | UNDEF, optional => 1 }, 'debug' => { type => SCALAR, optional => 1, default => 1 }, 'fatal' => { type => SCALAR, optional => 1, default => 1 }, 'test_mode' => { type => BOOLEAN, optional => 1, default => 0 }, } ); $prov->progress( num => 1, desc => 'gathering input' ); $p_user->{username} = $p{username}; $p_user->{uid} = $p{uid}; $p_user->{gid} = $p{gid}; $p_user->{debug} = $p{debug}; $p_user->{password} ||= $p{password}; $p_user->{shell} ||= $p{shell} ||= $prov->{config}{User}{shell_default}; $p_user->{homedir} ||= $p{homedir} || $prov->{config}{User}{home_base} eq '/home' ? "/Users/$p{username}" : "$prov->{config}{User}{home_base}/$p{username}"; $p_user->{gecos} ||= $p{gecos} || ''; $p_user->{expire} ||= $p{expire} || ''; $p_user->{quota} ||= $p{quota} || $prov->{config}{User}{quota_default}; $prov->progress( num => 2, desc => 'validating input' ); $p_user->_is_valid_request() or return; $prov->progress( num => 3, desc => 'dispatching' ); # return success if testing return $prov->progress( num => 10, desc => 'ok' ) if $p{test_mode}; # finally, create the user my $dirutil = $util->find_bin( "dscl", debug => $p{debug}, fatal => 0 ); $prov->progress( num => 5, desc => "adding Darwin user $p_user->{username}" ); if ($dirutil) { $self->_create_dscl(); } # 10.5+ else { $self->_create_niutil(); } # 10.4 and previous ## TODO # set the password for newly created accounts # validate user creation my $uid = $self->exists(); if ($uid) { $prov->progress( num => 10, desc => 'created successfully' ); return $uid; } return $prov->progress( num => 10, desc => 'error', err => $prov->{errors}->[-1]->{errmsg}, ); } sub _next_uid { # echo $[$(dscl . -list /Users uid | awk '{print $2}' | sort -n | tail -n1)+1] } sub _create_dscl { my $self = shift; my $user = $p_user->{username}; my $debug = $self->{debug}; my $dirutil = $util->find_bin( "dscl", debug => 0 ); $util->syscmd( "$dirutil . -create /users/$user", debug => $debug, ); $util->syscmd( "$dirutil . -createprop /users/$user uid $p_user->{uid}", debug => $debug, ); $util->syscmd( "$dirutil . -createprop /users/$user gid $p_user->{gid}", debug => $debug, ); $util->syscmd( "$dirutil . -createprop /users/$user shell $p_user->{shell}", debug => $debug, ); my $homedir = $p_user->{homedir}; $util->syscmd( "$dirutil . -createprop /users/$user home $homedir", debug => $debug, ) if $homedir; $util->syscmd( "$dirutil . -createprop /users/$user passwd '*'", debug => $debug, ); if ($homedir) { mkdir $homedir, 0755 or $util->mkdir_system( dir => $homedir, mode => '0755', debug => 0 ); $util->chown( dir => $homedir, uid => $user, debug => $debug ); } return getpwnam($user); } sub _create_niutil { my $self = shift; my $user = $p_user->{username}; my $debug = $p_user->{debug}; # use niutil on 10.4 and prior my $dirutil = $util->find_bin( "niutil", debug => 0 ); $util->syscmd( "$dirutil -create . /users/$user", debug => $debug, ) or croak "failed to create user $user\n"; $prov->progress( num => 6, desc => "configuring $user" ); $util->syscmd( "$dirutil -createprop . /users/$user uid $p_user->{uid}", debug => $debug, ); $util->syscmd( "$dirutil -createprop . /users/$user gid $p_user->{gid}", debug => $debug, ); $util->syscmd( "$dirutil -createprop . /users/$user shell $p_user->{shell}", debug => $debug, ); my $homedir = $p_user->{homedir}; $util->syscmd( "$dirutil -createprop . /users/$user home $homedir", debug => $debug, ); $util->syscmd( "$dirutil -createprop . /users/$user _shadow_passwd", debug => $debug, ); $util->syscmd( "$dirutil -createprop . /users/$user passwd '*'", debug => $debug, ); if ($homedir) { mkdir $homedir, 0755; $util->chown( dir => $homedir, uid => $user, debug => $debug ); } return getpwnam($user); } sub destroy { my $self = shift; my %p = validate( @_, { 'username' => { type => SCALAR }, 'debug' => { type => SCALAR, optional => 1, default => 1 }, 'test_mode' => { type => SCALAR, optional => 1, }, } ); my $user = $p{username}; $prov->progress( num => 5, desc => "destroy Darwin user $user" ); return $prov->progress( num => 10, desc => 'test completed' ) if $p{test_mode}; # this works on 10.5 my $dirutil = $util->find_bin( "dscl", debug => 0, fatal => 0 ); my $cmd; if ($dirutil) { # 10.5 $cmd = "$dirutil . -destroy /users/$user"; } else { # this works on 10.4 and previous $dirutil = $util->find_bin( "niutil", debug => 0 ); $cmd = "$dirutil -destroy . /users/$user"; } $util->syscmd( $cmd, debug => 0 ); return $self->exists($user) ? $prov->progress( num => 10, 'err' => 'failed' ) : $prov->progress( num => 10, desc => 'user destroyed' ); } sub create_group { my $self = shift; my %p = validate( @_, { 'group' => { type => SCALAR }, 'gid' => { type => SCALAR }, 'debug' => { type => SCALAR, optional => 1, default => 1 }, } ); my $group = $p{group}; my $gid = $p{gid}; $prov->progress( num => 5, desc => "adding Darwin group $group" ); my $dirutil = $util->find_bin( "dscl", debug => $p{debug}, fatal => 0 ); if ($dirutil) { # 10.5+ $util->syscmd( "$dirutil . -create /groups/$group", debug => $p{debug} ); $util->syscmd( "$dirutil . -createprop /groups/$group gid $gid", debug => $p{debug} ) if $gid; $util->syscmd( "$dirutil . -createprop /groups/$group passwd '*'", debug => $p{debug} ); } else { $dirutil = $prov->find_bin( "niutil", debug => $p{debug} ); $util->syscmd( "$dirutil -create . /groups/$group", debug => $p{debug} ); $util->syscmd( "$dirutil -createprop . /groups/$group gid $gid", debug => $p{debug} ) if $gid; $util->syscmd( "$dirutil -createprop . /groups/$group passwd '*'", debug => $p{debug} ); } return $self->exists_group( $p{group} ) ? $prov->progress( num => 10, desc => 'group added' ) : $prov->progress( num => 10, 'err' => 'failed!' ); } sub destroy_group { my $self = shift; my %p = validate( @_, { 'group' => { type => SCALAR }, 'gid' => { type => SCALAR, optional => 0 }, 'debug' => { type => SCALAR, optional => 1, default => 1 }, } ); my $group = $p{group}; my $gid = $p{gid}; $prov->progress( num => 5, desc => "destroy Darwin group $p{group}" ); my $dirutil = $util->find_bin( "dscl", debug => $p{debug}, fatal => 0 ); if ($dirutil) { # 10.5 $util->syscmd( "$dirutil . -delete /groups/$group", debug => $p{debug} ); } else { # =< 10.4 $dirutil = $util->find_bin( "niutil", debug => $p{debug} ); $util->syscmd( "$dirutil -delete . /groups/$group", debug => $p{debug} ); } return getgrnam( $p{group} ) ? $prov->progress( num => 10, 'err' => 'failed!' ) : $prov->progress( num => 10, desc => 'group deleted' ); } sub exists { my ( $self, $user ) = @_; $user ||= $p_user->{username}; $user = lc($user); my $uid = getpwnam($user); return ( $uid && $uid > 0 ) ? $uid : undef; } sub exists_group { my ( $self, $group ) = @_; $group or die "missing group"; my $gid = getgrnam($group); return ( $gid && $gid > 0 ) ? $gid : undef; } 1; __END__